RFC-0043:文档注释格式 | |
---|---|
状态 | 已接受 |
区域 |
|
说明 | 此 FTP 采用了单一格式来编写文档注释。此格式可供以其他人类可读且可供机器使用的格式(例如HTML、Markdown)。 |
作者 | |
提交日期(年-月-日) | 2019-05-06 |
审核日期(年-月-日) | 2019-05-30 |
摘要
此 RFC 标准化了用于编写文档注释的单一格式。此格式可供以其他人类可读且可供机器使用的格式(例如HTML、Markdown)。
设计初衷
我们目前提供了一个 API 文档评分标准,其中明确说明了需要记录 FIDL 代码的哪些方面,包括参数、返回值和错误。我们还鼓励开发者提供 API 使用示例。不过,我们尚未向开发者提供在 FIDL API 文档中清晰表达这些功能的方法。
随着 fidldoc
工具的出现,为开发者提供一种在注释中表达格式的途径变得更加重要。编写注释的开发者应了解如何在输出中设置列表格式,例如。他们还必须知道如何指明某个内容是返回值还是参数,以便在输出中正确显示该内容。
设计
要点:我们希望使用 Markdown 来添加评论。当然,细节决定成败。
此 RFC 修改了 API 文档评分标准,以及我们用于处理 FIDL API 文档的工具。这不会影响 FIDL 语言,因为一组合法的 FIDL 保持不变。
为什么使用 Markdown?
文档注释的解决方案空间可分为两部分:“自行开发解决方案”和“使用现有解决方案”。我们认为,FIDL 的生态系统规模不足以支持为注释语法开发单独的标准。通过使用现有解决方案,开发者将能够利用外部文档和工具(以及可能的现有知识)。此外,通过使用现有解决方案,我们可以节省开发时间。
如果我们决定使用现有解决方案,就必须选择一个。有几种特定于语言的解决方案可以扩展(例如 javadoc 和 Python 文档字符串)。还有一些通用解决方案(例如LaTeX、RST、Markdown)。
我们认为 Markdown 是最佳选择。与特定语言的解决方案不同,有许多工具可将 Markdown 集成到新语言中。Markdown 也广泛为开发者所用和了解:例如,GitHub 就使用 Markdown 编写文档。最后,某些语言(例如Rust 和 Kotlin)正在将其语法标准化为 Markdown,并且它也开始取代其他语言中的现有解决方案(例如,LLVM 将从 RST 迁移到 Markdown)。
什么是 Markdown?
Markdown 有多种实现,行为略有不同。其中任意数量的选项都是合理的选择。我们选择 CommonMark,因为它是最接近标准的。 对于工具需要同时定位到 CommonMark 和其他 Markdown 实现的开发者,我们建议尽可能使其文档与这两者兼容。
Markdown 不可扩展,因此无法帮助您表达语言元素。我们添加了可由 fidldoc
(以及其他 API 文档使用工具)处理的 Markdown 专用扩展。
文档注释采用 Markdown 格式编写,位于要记录的元素之前。它包含一个说明,可选地后跟有关参数、错误和“see”(表示读者应查看所引用的 API 以了解详情)的文档。
参数和错误
应记录请求参数:
* request `paramname` Description of parameter
应记录响应参数:
* response `paramname` Description of parameter
我们还将 param
和 return
或 in
和 out
视为关键字,而不是 request
和 response
。
如果该方法不使用相同的标识符作为请求和响应的参数,则 request
和 response
是可选的。
返回无参数值 (Foo() -> ()
) 的方法可以使用术语 response
,而无需对应的参数来进行文档编写。
错误子句应记录在以下位置:
* error Description of error values
完全限定名称
完全限定名称的格式为:
<library>/<top level declaration>.<member>
这将唯一标识任何成员,因为没有重载。
目前,序数哈希基于采用 <library>.<top
level declaration>/<member>
格式的名称(请参阅 RFC-0020),fidlc
使用 <library>.<top level declaration>/<member>
格式报告错误。我们打算让这些内容采用上述明确的格式。我们将修改 RFC-0029:递增方法序数,以使用 <library>/<top level declaration>.<member>
作为经过哈希处理的名称,并修改 fidlc
以一致地报告错误。
通过添加 [`link-target`],可以链接到其他与文档关联的 FIDL 语言元素(或已记录的实体)。例如,[“fidl.io/NodeInfo”] 链接到该库的文档。分辨率规则如下:
- 首先,系统会检查嵌套元素。如果您要记录
struct Object
,并且它包含成员event
,则可以将其引用为 [`event`]。 - 接下来,系统会检查与记录的元素处于同一作用域级别的元素。例如,如果您要记录协议方法
foo()
,而同一协议包含方法bar()
,则可以将其称为 [`bar`]。 - 接下来,系统会检查封闭作用域的元素(如果有)。例如,如果您要为协议方法
foo()
编写文档,并且同一库中还有另一个名为Info
的协议,则可以通过 [`Info`] 来引用该协议及其元素。 - 在连续封闭的范围中重复 3,直到您到达顶级范围。如果您要记录协议方法
foo()
,并编写 [`fuchsia.io/NodeInfo`],则它将引用联合体fuchsia.io/NodeInfo
。
完全限定名称采用 <library>/<top level
declaration>.<member>
格式,请参阅上文中的详细信息。
对于其他链接快捷方式,您可以指定链接目标,例如:
[fuchsia-concepts]: https://fuchsia.dev/fuchsia-src/concepts
该行不会显示在工具输出中。
如果工具在运行时知道给定的 FIDL 目标类型,则无需指定位置。例如,在同一工具调用中,系统可能会生成 fuchsia.sys/ComponentController
和 fuchsia.sys/EnvironmentController
的文档。该工具会了解它们之间的关联。
开发者还可以使用以下方式指明存在相关 API:
* see [`fidl.io`]
(如果适用)。
实施策略
实现包括将其添加到 FIDL 评分标准、对其进行公开以及将特殊注解纳入 fidldoc
工具。我们还可以为 fidldoc
语法添加 lint 检查,将其添加到 fidl-lint
工具或单独的工具中。
文档和示例
完整示例如下所示。 请注意,此 API 目前并非如此;我们已将状态更改为“错误”以作说明。
library fuchsia.io;
protocol File {
/// Acquires a [`fuchsia.mem/Buffer`] representing this file, if
/// there is one, with the requested access rights.
///
/// ## Rights
///
/// This method requires the following rights:
///
/// * [`OPEN_RIGHT_WRITABLE`] if `flags` includes
/// [`VMO_FLAG_WRITE`].
/// * [`OPEN_RIGHT_READABLE`] if `flags` includes
/// [`VMO_FLAG_READ`] or [`VMO_FLAG_EXEC`].
///
/// + request `flags` a bit field composing any of
/// `VMO_FLAG_READ`, `VMO_FLAG_WRITE`, or `VMO_FLAG_EXEC`.
/// - response `buffer` the requested [`fuchsia.mem/Buffer`], or
/// null if there was an error, or the buffer does not exist.
/// * error a `zx.status` value indicating success or failure.
/// * see [Filesystem architecture][fs-arch] for further details.
///
/// [fs-arch]: https://fuchsia.dev/fuchsia-src/concepts/filesystems/filesystems
GetBuffer(uint32 flags) ->
(fuchsia.mem.Buffer? buffer) error zx.status;
};
请注意,按照惯例,您只需在给定文档注释中链接到元素的第一个引用即可。上述对 VMO_FLAG_READ
的第一个引用已关联,而第二个引用未关联。
向后兼容性
没有重大的向后兼容性问题。当前文档使用 C++ 风格的 |param|
表示法来指明参数和返回值。这相对来说比较容易更改。
性能
这会增加开发者输入的字符数,进而影响开发速度,但同时也会让开发者了解更多。
缺点、替代方案和未知情况
假设采用格式比不采用格式要好得多。因此,缺点很少。
替代方案可能包括其他 API 文档格式。Java 使用 Javadoc,它非常详尽且依赖于内嵌 HTML。开发者会觉得很痛苦。其他语言使用 RST。不过,这种方式越来越不受欢迎;开发者更熟悉 Markdown。值得注意的是,LLVM 项目正在从 RST 迁移到 Markdown。
我们考虑过使用 Markdown 的其他变体。我们之所以选择使用 CommonMark,是因为它是经过最完善规范的 Markdown 实现。如果开发者需要其代码在其他 Markdown 渲染系统中正常运行,则应尝试编写符合 CommonMark 和目标系统的文档注释。
我们考虑过不为关联记录的实体发明新的语法。 我们考虑的替代方案包括:
- 自动检测。 在其他情境中使用自动检测机制的经验表明,它们很少检测到开发者预期的内容。此外,自动检测功能还可防止工具显示链接错误这一事实。因此,我们将自动检测功能的相关工作推迟到日后。
- 使用现有语法。这与自动检测有相同的问题,但症状略有缓解。如果我们使用
fuchsia.io/NodeInfo
作为语法,那么如果拼写有误,则不会显示链接,而只会显示代码字体。我们希望工具能够检测损坏的链接,而不是采用回退行为。
我们日后应考虑但不在本 RFC 范围内的事项包括:
- 将图片或流程图嵌入到生成的文档中的方法。
- 将自动检查的示例嵌入到文档中的方法。
在先技术和参考文档
此提案深受 Rust 和 Kotlin 文档样式的启发。