RFC-0058:引入已弃用的属性 | |
---|---|
状态 | 已接受 |
领域 |
|
说明 | 使用新属性“已弃用”来指示弃用类型(枚举、结构体、联合、使用声明)、常量、方法或整个接口。沿用这一建议,以尽可能最好地定位语言。 |
作者 | |
提交日期(年-月-日) | 2018-09-10 |
审核日期(年-月-日) | 2018-10-11 |
总结
使用新属性 [Deprecated]
来指示弃用类型(枚举、结构体、联合、使用声明)、常量、方法或整个接口。沿用这一建议,以尽可能最好地定位语言。
与其他 RFC 的关系
此 RFC 已被取代:
设计初衷
有许多注释表明不应再使用某个类型、方法或接口。请点击此处或此处查看示例。 通过对一种用于传达废弃情况的方法进行标准化,在 JSON IR 中公开这些信息,并在各种语言后端利用这些信息,我们能够以目标语言将这些注释转换为警告,从而更轻松地为使用 API 的开发者提供指导。
今日使用情况调查
使用“ack --type=fidl -i 'deprecated' -A 2 -B 2
”开展的问卷调查
- On 方法
- fuchsia.io/Ioctl
- fuchsia.tracelink/RegisterTraceProviderDeprecated 已弃用
- fuchsia.modular/GetAuthenticationContext
- fuchsia.modular/GetActiveLinks
- fuchsia.modular/Duplicate
- fuchsia.modular.module/ 改为使用 StartOngoingActivity
- fuchsia.mediaplayer/SetReaderSource
- fuchsia.ui.viewsv1/AddChild
- fuchsia.ui.viewsv1/RemoveChild
- fuchsia.ui.viewsv1/CreateView
- fuchsia.testing.runner/Fail
- fuchsia.netstack/GetNodeName
- fuchsia.netstack/SetRouteTable
- On 字段
- fuchsia.modular/CreateStory - module_url 参数
- fuchsia.modular/CreateStoryWithInfo - module_url 参数
- fuchsia.modular.intent/ json -> entity_reference
- 在接口上
- fuchsia.simplecamera.SimpleCamera
- fuchsia.sys.ServiceProvider
- fuchsia.media.AudioOut
- fuchsia.media.AudioIn
设计
建议并记录使用 [Deprecated]
属性。
(可选)可以添加备注来提供有关弃用方式和首选替代方案的说明,例如 [Deprecated = "explanation"]
。
不更改 FIDL 编译器。
虽然我们可能希望针对使用已废弃类型或消息显示废弃警告,尤其是跨库边界,但我们会选择一个最低限度的实现。出于这一原因,我们既希望了解这些 [Deprecated]
属性的实际使用情况,又希望避免编译器中出现我们无法确定的复杂问题。
更改各种语言后端,如下一部分中详细介绍:
在 Rust 中,视情况添加
#[deprecated]
或#[deprecated(note = "explanation")]
。在 Dart 中,视情况添加
@Deprecated
。如果提供了说明,还可以考虑添加自动评论。在 Go 中,根据需要添加注释
// Deprecated.
或// Deprecated: explanation.
。(请参阅三种推荐的表单。)在 C++ 中,视情况添加
[[deprecated]]
或[[deprecated("explanation")]]
。
最后,我们要记录此功能。 建议您在 API 评分准则中的“Good Design Patterns”下对此进行讨论。
关于在目标语言中弃用展示位置的详细说明
以 FIDL 表示 | 采用目标语言 |
---|---|
类型别名(例如,使用 foo = bar;) | 没有影响,目前类型别名只关注前端,不显示在 JSON IR 中。 |
常量声明 | 针对所定义的常量发出提醒,以便在使用该常量时发出警告。 |
消息(例如 struct、union、table) | 表示 FIDL 消息的顶级类型(类/结构体)上的注解,即最终开发者使用的类型。 |
字段(例如结构体字段、表字段) | 在表示特定 FIDL 字段的类型字段中,和/或此字段的所有访问器方法上(例如 ClearXxx、SetXxx 等) |
方法、事件或接口 | 放置在面向客户端的对象/函数(例如代理)上,但不放置在面向服务客户端的对象/函数上(例如,不在桩上);请参阅以下说明。 |
备注
我们可以引入 [DeprecatedForClients]
和 [DeprecatedForServices]
属性来控制将弃用哪一端,但弃用节目主要是为了告知消费者。
作为错误弃用
目标语言中的废弃注解可能会出现错误,具体取决于构建设置和 pragma。
例如,在 Rust 中,#deprecated
属性会引发警告。不过,这往往与 crate 级 #![deny(warnings)]
结合使用,后者会将所有警告提升为错误。这反过来又会强制使用已废弃的函数、变量和方法的用户在使用时指定 #allow(deprecated)
。此特定使用网站正确记录了故意使用已废弃代码的意图。
另一个例子是,Go 对弃用警告的支持并不直接,需要求助于第三方工具,例如 staticcheck.io。
因此,FIDL 库的作者应注意,引入 [Deprecated]
属性是一项源代码级别的破坏性更改,在大多数情况下,该库的用户需要新注解。
实施策略
有两个观察结果:
- 每个语言后端都可以独立实现。
[Deprecated]
属性可以在独立于后端支持的各种 .fidl 文件中引入。
建议的策略是,将临时注释转换为这个提议的属性,以便开始在各种 .fidl 文件中使用 [Deprecated]
属性。
在单独的更改中,应对 Dart、Rust 和 C++,因为它们有一些目标语言支持。
对于 Go,我们希望在使用文档注释的同时实现此更改。(特别是因为弃用通知需要与文档注释正确融合,所以一般样式是添加文档注释、换行,然后是弃用通知。)
至于文档,此更改应在 .fidl 文件中使用该属性后不久,或在一种语言后端首次实现后发生。
文档和示例
在 API 评分准则的“良好设计模式”部分下添加“弃用”子部分。此外,请将此属性与其他属性一起记录下来。
向后兼容性
无影响。
性能
无影响。
安全性
无影响。
测试
测试在每个后端代码生成级别完成。
缺点、替代方案和未知情况
系统会衡量此方案的实现费用,并且一次只能在每个语言后端计算一个费用。此外,此惯例的存在将阐明如何表明弃用,并提供有关为现有 FIDL 文件添加注解的指南。
作为替代方案,我们可以选择不实现任何内容,也不为任何废弃指示提供支持。如果不进行任何操作,我们此时就可以避免采用一种特定方式来表示废弃,尤其是在我们看到更多人使用这种形式之前。(快速确认搜索可找到 20 到 25 个地点。)
我们还可以引入一个要废弃的语言关键字,并将其作为语法的一部分。这似乎过于严格且复杂,尤其是对于在文档之外没有语义意义的功能。
早期技术和参考资料
能够描述弃用并指向替代方案是多种编程语言(如上文所述)的一项常见功能。
在 protobuf 中,只能对字段弃用:“如果设置为 true,则表示该字段已弃用,新代码不应使用该字段。对于大多数语言,这不会产生实际影响。 在 Java 中,这变成了 @Deprecated 注释。 将来,其他语言的代码生成器可能会在字段的访问器上生成废弃注释,这反过来会导致在编译试图使用该字段的代码时发出警告。如果该字段未供任何人使用,并且您想要防止新用户使用它,请考虑将字段声明替换为预留语句。”
Mojo 和 Thrift 似乎没有这样的功能。
FlatBuffers(仅针对字段):“不再为此字段生成访问器,代码应停止使用此数据。”