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

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

使用新的 Deprecated 屬性,指出型別 (列舉、結構體、聯集、使用宣告)、常數、方法或整個介面已淘汰。並以最佳方式將這些內容轉譯為目標語言。

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

摘要

使用新屬性 [Deprecated] 指出型別 (列舉、結構體、聯集、使用宣告)、常數、方法或整個介面已遭淘汰。並以最佳方式將這些內容轉譯為目標語言。

與其他 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),但不要放在面向服務用戶端的物件/函式 (例如不要放在存根);請參閱下方附註

注意事項

我們可以導入 [DeprecatedForClients][DeprecatedForServices] 屬性,控管要淘汰哪一側,但使用淘汰項目主要是為了通知消費者。

將淘汰項目視為錯誤

視建構設定和 pragma 而定,目標語言中的淘汰註解會引發錯誤。

舉例來說,在 Rust 中,#deprecated 屬性會引發警告。不過,這通常會與 Crate 層級的 #![deny(warnings)] 搭配使用,將所有警告提升為錯誤。這會強制已淘汰函式、變數和方法的使用者,在使用的時間點指定 #allow(deprecated)。這個特定使用網站會適當記錄有意使用已淘汰程式碼的意圖。

以 Go 語言為例,對淘汰警告的支援並非直接提供,而是需要使用 staticcheck.io 等第三方工具。

因此,FIDL 程式庫作者應注意,導入 [Deprecated] 屬性是來源層級的重大變更,在大多數情況下,程式庫使用者都需要新增註解。

導入策略

有兩項觀察結果:

  • 每種語言後端都可以獨立實作。
  • [Deprecated] 屬性可獨立於後端支援,在各種 .fidl 檔案中導入。

建議您開始在各種 .fidl 檔案中使用 [Deprecated] 屬性,方法是將臨時註解轉換為這個建議的屬性。

在其他變更中,處理 Dart、Rust 和 C++,因為這些語言支援部分目標語言。

如果是 Go,我們會想實作這項變更,並使用文件註解。(特別是因為淘汰通知需要與文件註解正確合併,一般做法是加入文件註解、換行,然後加入淘汰通知)。

至於文件,這項變更應會在 .fidl 檔案中使用這個屬性後,或在某種語言後端首次實作後不久發生。

說明文件和範例

在「Good Design Patterns」(良好設計模式) 區段下方的 API 評分量表中,新增「Deprecation」(淘汰) 子區段。此外,請記錄這項屬性和其他屬性

回溯相容性

沒有影響。

效能

沒有影響。

安全性

沒有影響。

測試

測試會在每個後端程式碼生成層級進行。

缺點、替代方案和未知事項

系統會評估這項提案的實作成本,且每次只能在一個語言後端完成。此外,這項慣例的存在本身就會說明如何指出淘汰,並提供現有 FIDL 檔案的註解指南。

或者,我們也可以選擇不實作任何內容,且不提供任何淘汰指標的支援。如果暫時不採取任何行動,我們就不必急著決定要以哪種方式標示淘汰,尤其是在我們還不清楚這項功能的使用情況時。(快速確認搜尋結果會顯示約 20 到 25 個地點)。

我們也可以導入語言關鍵字來表示淘汰,並將其納入文法。但這似乎過於嚴格和複雜,尤其是對於沒有文件以外語意意義的功能。

既有技術和參考資料

能夠說明淘汰情形並指出替代方案,是多種程式設計語言的常見功能 (如上所述)。

在通訊協定緩衝區中,只能對欄位進行淘汰:「如果設為 true,表示該欄位已淘汰,新程式碼不應使用。在大多數語言中,這不會產生實際效果。 在 Java 中,這會變成 @Deprecated 註解。日後,其他語言專屬的程式碼產生器可能會在欄位的存取子產生淘汰註解,進而導致編譯嘗試使用該欄位的程式碼時發出警告。如果沒有人使用該欄位,且您想禁止新使用者使用,請考慮以保留陳述式取代欄位宣告。」

Mojo 和 Thrift 似乎沒有類似功能。

Flatbuffers,僅限於欄位:「不再為這個欄位產生存取子,程式碼應停止使用這項資料。」