| RFC-0058:導入已淘汰的屬性 | |
|---|---|
| 狀態 | 已接受 |
| 區域 |
|
| 說明 | 使用新的 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,僅限於欄位:「不再為這個欄位產生存取子,程式碼應停止使用這項資料。」