RFC-0043:文档注释格式

RFC-0043:文档注释格式
状态已接受
领域
  • FIDL
说明

该 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 doc 字符串)。还有一些通用解决方案(例如,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

此外,我们还考虑了 paramreturn(或 inout)作为关键字,而不是 requestresponse

如果方法未使用相同的标识符作为请求和响应的参数,则 requestresponse 为可选项。

返回没有参数值的方法 (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: Incrusing Method Ordinals,将 <library>/<top level declaration>.<member> 用作经过哈希处理的名称,并修改 fidlc 以一致地报告错误。

通过添加 [`link-target`],可以链接到具有相关文档的其他 FIDL 语言元素(或记录的实体)。例如,[`fidl.io/NodeInfo`] 可以链接到上述库的文档。解决规则如下:

  1. 首先,系统会检查嵌套元素。如果您正在记录 struct Object,并且它包含成员 event,则可以将其称为 [`event`]。
  2. 接下来,系统会检查与所记录元素处于同一作用域级别的元素。 例如,如果您要记录一个协议方法 foo(),而同一协议包含方法 bar(),您可以将其称为 [`bar`]。
  3. 接下来,系统会检查封闭范围的元素(如果有)。 例如,如果您要记录一个协议方法 foo(),并且同一库中还有一个名为 Info 的协议,则可以通过说出 [`Info`] 来引用它(及其元素)。
  4. 3 在连续封闭的范围中重复出现,直到您位于顶级范围为止。 如果您要记录协议方法 foo() 并编写 [`fuchsia.io/NodeInfo`],它将引用联合 fuchsia.io/NodeInfo

完全限定名称的格式为 <library>/<top level declaration>.<member>,请参阅上文的详细信息

对于其他链接快捷方式,您可以指定链接目标,例如:

[fuchsia-concepts]: https://fuchsia.dev/fuchsia-src/concepts

该行不会显示在工具输出中。

如果工具在运行时是已知的 FIDL 目标类型,则无需指定位置。 例如,fuchsia.sys/ComponentControllerfuchsia.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 文档样式的影响很大。