RFC-0054:参数属性

RFC-0054:参数属性
状态已接受
领域
  • FIDL
说明

我们已经可以将属性应用于 FIDL 的各种元素,但不能应用于参数。此建议旨在扩展语法以接受参数属性。

作者
提交日期(年-月-日)2019-11-21
审核日期(年-月-日)2019-12-12

“有机会编写自文档的 API”

总结

我们已经可以将属性应用于 FIDL 的各种元素,但不能应用于参数。此建议旨在扩展语法以接受参数属性。

与其他 RFC 的关系

此 RFC 已被取代:

设计初衷

为更多语言元素设置属性可以提高语言一致性,也是未来推出更多功能的驱动因素。任何无法在类型系统中编码的 API 事实都可以改为在属性中进行编码。任何无法在类型系统中编码的事实,都可以通过属性中的更多结构来捕获,从而简化各种后端中的后期验证。这些属性对执行 lint 请求非常有用,生成器也可以利用这些信息生成更好的代码,或将其传播到目标语言的属性。这有助于对目标语言进行静态和/或动态分析。此外,属性也是为类型系统进行可能的扩展或优化设计原型的好方法。

此功能的驱动用例是检查句柄泄漏、双重释放以及在释放错误后使用。

内核 ABI(即系统调用)也以 FIDL 格式表示,并且句柄的所有权通常不明确。用户是否应在 task_kill 系统调用之后调用 handle_close?文档中未明确说明这一点。其他系统调用具有非常清晰的文档,但只能手动检查:

[Transport = "Syscall"]
protocol handle {
    /// Close a handle.
    /// Rights: None.
    handle_close(handle handle) -> (status status);

    /// Close a number of handles.
    /// Rights: None.
    handle_close_many(vector<handle> handles) -> (status status);

    /// Duplicate a handle.
    /// Rights: handle must have ZX_RIGHT_DUPLICATE.
    handle_duplicate(handle handle, rights rights) -> (status status, handle out);

    /// Replace a handle.
    /// Rights: None.
    handle_replace(handle handle, rights rights) -> (status status, handle out);
};

在针对参数启用属性后,我们就可以将注释替换为属性。这些属性与注释一样可读,可帮助生成器生成可以使用此处的静态和动态分析工具进行检查的代码。Kazoo 工具可以为 C 和 C++ 绑定生成相应的注解,使 Clang Static Analyzer 能够捕获句柄误用错误。

该原型已经在 Fuchsia 中发现了许多错误。

设计

我们提议以 FIDL 源语言添加参数属性。这些属性应以与其他属性类似的方式在 JSON IR 中公开。我们可能需要更新格式设置工具。而不会影响传输格式。语言绑定只会受到可更改所生成代码的特定注解的影响,但不会受到此方案的直接影响。

我们的方案仅更改 FIDL 语法的一条生成规则:

- parameter = type-constructor , IDENTIFIER ;
+ parameter = ( attribute-list ) , type-constructor , IDENTIFIER ;

我们还需要诊断三斜杠文档或参数的文档属性。

实施策略

此更改可向后兼容,无需迁移。有很多文档需要随该功能一起更新。此方案将更改解析器并向 IR 添加新信息。在引入新的参数属性时,可以单独对生成器进行潜在的更改。

工效学设计

它有望使 FIDL API 更易于理解,并使其更有利于静态和动态分析。额外的复杂性成本应该很低。如需查看可能的参数属性的示例,请参阅下一部分。 编辑器支持可能也需要小幅更新。

文档和示例

语法文档和语言参考文档需要进行细微更新。在某些情况下,我们可能需要为参数属性添加一些样式准则,以了解如何换行。这可能不是很重要,因为当前的样式指南中根本没有提到属性。

如需查看示例,请参阅“动机”部分

向后兼容性

此方案同时保持 FIDL 源代码和线上 ABI 的兼容性。后来引入的特定属性可能会导致线上 ABI 不兼容。要单独通过 RFC 流程,必须具备这些属性。

性能

未来的属性可能会对性能产生很好的影响。有关 API 的更多信息可能对目标语言的优化器有所帮助。

安全性

特定属性可以提高安全性,因为它们可以帮助采用目标语言的静态和动态分析工具。

测试

系统将针对 fidlc 编写测试,以确保正确解析,并对编译失败进行合理的诊断。系统还将测试生成的 JSON IR。为了能够进行测试,我们需要至少引入一个适用于参数的属性。由于一开始不会涉及生成器,因此它们不需要进行额外的测试。

缺点、替代方案和未知情况

实现成本相对较低。

RFC-0044 是一个可能的替代方案。接受该方案会导致语言中存在一些不一致,因为描述参数的一种方式可让用户写入参数属性,而另一种方式则不能。此外,RFC-0044 具有性能成本,因此某些协议(如系统调用)应谨慎使用或完全不使用 RFC-0044。

早期技术和参考资料

Protobuf 提供针对消息的选项,其行为与参数属性有一些类似的行为。FIDL 已经在一些语言元素(如成员和协议)上具有属性。