RFC-0058:引入已淘汰的屬性

RFC-0058:引入已淘汰的屬性
狀態已接受
區域
  • FIDL
說明

使用新的「Deprecated」屬性,表示已淘汰的類型 (列舉、結構體、聯集、使用宣告)、常數、方法或整個介面。以最佳方式將其轉換為目標語言。

作者
提交日期 (年-月-日)2018-09-10
審查日期 (年-月-日)2018-10-11

摘要

使用新的屬性 [Deprecated] 來表示類型 (列舉、結構體、聯集、使用宣告)、常數、方法或整個介面的淘汰。以最佳方式將其轉換為目標語言。

與其他 RFC 的關係

此 RFC 已由下列 RFC 取代:

提振精神

我們有許多註解指出不應再使用某類型、方法或介面。請參閱這篇文章這篇文章中的示例。我們將淘汰資訊的通報方式標準化,並在 JSON IR 中公開這項資訊,同時在各種語言後端中運用這項資訊,就能將這些備註轉換為以目標語言撰寫的警告,方便開發人員使用 API。

今天的使用者調查

使用「ack --type=fidl -i 'deprecated' -A 2 -B 2」進行調查

  • 關於方法
    • 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
  • 在欄位上
    • 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 評量準則的「良好設計模式」下方討論這個問題。

在目標語言中放置淘汰資訊的具體細節

在 FIDL 中 在目標語言中
類型別名 (例如使用 foo = bar;) 無影響,目前型別別名僅是前端問題,不會在 JSON IR 中顯示。
Const 宣告 在定義常數時,以便在使用常數時發出警告。
訊息 (例如結構體、聯集、表格) 代表 FIDL 訊息的頂層類型 (類別/結構體) 上的註解,也就是最終開發人員使用的類型。
欄位 (例如結構體欄位、資料表欄位) 在代表特定 FIDL 欄位的類型欄位,和/或此欄位的所有存取方法 (例如 ClearXxx、SetXxx 等) 上
方法、事件或介面 請將此方法放置在用戶端面向物件/函式 (例如 Proxy) 上,但不要放置在服務用戶端面向物件/函式 (例如 Stub) 上;請參閱下方附註

注意事項

我們可以導入 [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,僅限欄位:「請勿再為此欄位產生存取器,程式碼應停止使用此資料。」