| RFC-0043:文档注释格式 | |
|---|---|
| 状态 | 已接受 |
| 区域 |
|
| 说明 | 此 FTP 针对编写文档注释标准化为单一格式。此格式可供以其他人类可读和机器可读格式(例如 HTML、Markdown)。 |
| 作者 | |
| 提交日期(年-月-日) | 2019-05-06 |
| 审核日期(年-月-日) | 2019-05-30 |
摘要
此 RFC 标准化了用于编写文档注释的单一格式。 此格式可供以其他人类可读和机器可读格式(例如,HTML、Markdown)。
设计初衷
我们目前有一个 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 不可扩展,因此无法帮助您表达语言元素。
我们添加了可由 fidldoc(以及其他 API 文档使用工具)处理的 Markdown 专用扩展程序。
文档注释以 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 文档风格的影响。