RFC-0058:引入了已弃用的属性

RFC-0058:引入已弃用的属性
状态已接受
领域
  • FIDL
说明

使用新属性“已弃用”来指示弃用类型(枚举、结构体、联合、使用声明)、常量、方法或整个接口。沿用这一建议,以尽可能最好地定位语言。

作者
  • pascallouis@google.com
提交日期(年-月-日)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(仅针对字段):“不再为此字段生成访问器,代码应停止使用此数据。”