| RFC-0043:文档注释格式 | |
|---|---|
| 状态 | 已接受 |
| 区域 |
|
| 说明 | 此 FTP 针对编写文档注释标准化为单一格式。此格式可供以其他人类可读和机器可读格式(例如 HTML、Markdown)生成 API 文档的工具使用。 |
| 作者 | |
| 提交日期(年-月-日) | 2019-05-06 |
| 审核日期(年-月-日) | 2019-05-30 |
摘要
此 RFC 针对编写文档注释标准化为单一格式。 此格式可供以其他人类可读和机器可读格式(例如 HTML、Markdown)生成 API 文档的工具使用。
设计初衷
我们目前有一个 API 文档评分准则,该准则非常清楚地说明了需要记录 FIDL 代码的哪些方面,包括参数、返回值和错误。我们还鼓励开发者提供 API 用法示例。 不过,我们尚未为开发者提供在 FIDL API 文档中表达这些功能的明确方式。
随着 fidldoc 工具的出现,为开发者提供一种在注释中表达格式的方式变得越来越重要。
编写注释的开发者应知道如何在输出中设置列表格式。
他们还必须知道如何指明某项是返回值还是参数,以便在输出中正确显示。
设计
TL;DR: 我们希望使用 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 不可扩展,因此无法帮助您表达语言元素。
我们添加了 Markdown 的专用扩展,这些扩展可由 fidldoc(和其他 API 文档使用工具)处理。
文档注释以 Markdown 编写,并位于其记录的元素之前。 它包含说明,后跟有关参数、错误和“请参阅”(表示读者应查看引用的 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 以一致地报告错误。
如需链接到其他具有关联文档的 FIDL 语言元素 (或 已记录的实体),可以添加 [`link-target`]。 例如,[`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 呈现系统中运行,则应尝试编写同时符合 CommonMark 和目标系统的文档注释。
我们考虑不为链接已记录的实体发明新语法。 我们考虑的替代方案包括:
- 自动检测。 在其他情境下使用自动检测机制的经验表明,它们很少检测到开发者想要的内容。 此外,自动检测会阻止工具显示链接错误的事实。 因此,我们将自动检测工作推迟到未来。
- 使用现有语法。
这与自动检测存在相同的问题,但症状稍微好一些。
如果我们使用
fuchsia.io/NodeInfo作为语法,那么如果拼写错误,链接将不会存在,并且我们只会得到代码字体。 我们希望工具能够检测到损坏的链接,而不是采用回退行为。
我们将来应考虑但超出此 RFC 范围的事项包括:
- 将图片或流程图嵌入到生成的文档中的方法。
- 将自动检查的示例嵌入到文档中的方法。
在先技术和参考文档
此提案深受 Rust 和 Kotlin 的文档样式的影响。