RFC-0040:識別碼唯一性

RFC-0040:識別碼不得重複
狀態已接受
領域
  • FIDL
說明

FIDL 規格和前端編譯器目前根據簡單的字串比較,會將兩個 ID 視為不同。這是一個新的演算法,可將繫結產生器產生的轉換納入考量。

作者
提交日期 (年-月-日)2019-04-08
審查日期 (年-月-日)2019-05-14

「雪花白 vs SNOW_FLAKE」

摘要

FIDL 規格和前端編譯器目前會考慮兩個 識別字串。 這建議建立新的演算法,將轉換納入考量 建立繫結器的原理

提振精神

語言繫結產生器會轉換 ID 以符合目標 將多個 FIDL ID 對應至單一 ID 的語言限制和樣式 目標語言 ID 這可能導致非預期的衝突,只有在特定情況下才會可見 語言。

設計

這提議對不存在的 FIDL ID 實施限制 程式庫違反規則。 不會變更 FIDL 語言、IR (目前為 1)、繫結和樣式 指南或評分量表

實際上,ID 是由一連串的字詞組成。 彙整字詞的常見方法是 CamelCase,這是進行轉換的 由低到大寫表示文字邊界,而 snake_case,其中之一或 有許多底線 (_) 用來分隔字詞。

請將 ID 轉換為標準格式,以便進行比較。這將 為 lower_snake_case 形式,並保留原始字詞中的字詞分隔 表單中要求的資訊。字詞有不完整的情況 (1) 使用底線,(2) 轉場效果 小寫或數字變更為大寫,以及 (3) 從大寫改為大寫 小寫。

在 FIDL 中,必須以原格式使用 ID, 因此,如果類型名稱為 FooBar,就會嘗試將其視為 foo_bar 錯誤。

有簡單的演算法可以執行這項轉換 這裡的 Python 語言2

def canonical(identifier):
    last = '_'
    out = ''
    for i, c in enumerate(identifier):
        is_next_lower = i + 1 < len(identifier) and identifier[i+1].islower()
        if c == '_':
            if last != '_':
                out += '_'
        elif (((last.islower() or last.isdigit()) and c.isupper())
              or (last != '_' and c.isupper() and is_next_lower)):
            out += '_' + c.lower()
        else:
            out += c.lower()
        last = c
    return out

以下列舉幾個不同目標語言的可能翻譯範例:

FIDL ID 標準形式 C++ 荒漠油廠 查看 飛鏢
foobar foobar foobar foobar Foobar foobar_
foo_bar foo_bar foo_bar foo_bar FooBar fooBar_
foo__bar foo_bar foo_bar foo_bar FooBar fooBar_
FooBar foo_bar foo_bar foo_bar FooBar fooBar_
fooBar foo_bar foo_bar foo_bar FooBar fooBar_
FOOBar foo_bar foo_bar foo_bar FooBar fooBar_

執行策略

系統會更新前端編譯器,以檢查每個新 ID 的 標準格式不會與其他 ID 的標準格式相衝突。

下一個版本的 FIDL IR 應根據標準名稱來整理 而不是原名,但原始名稱也會成為 。 如果我們能排除在產生的繫結中使用未經修改的名稱, 原始名稱可以從 IR 中刪除。

人體工學

這也界定了現有的 FIDL 語言限制。

說明文件和範例

FIDL 語言說明文件將更新以說明這項限制。 這個模型會擴大以納入 設計一節。

因為這個提案會將現有的做法、範例和 教學課程不會受到影響。

回溯相容性

受這項異動影響的現有 FIDL 程式庫都違反我們的 樣式指南,而且不支援許多語言繫結。 但這不會改變用於計算序數的 ID 形式。

成效

這會對前端編譯器造成少許費用。

安全性

沒有影響。

測試

標準化演算法會進行大量測試 在 fidlc 中實作。 也會進行 fidlc 項測試,確保能在 宣告相衝突的 ID,並確保原始名稱 參照宣告,

缺點、替代方案和未知

其中一個做法是不執行任何動作。 我們通常會在非 C++ 產生的繫結中發生建構失敗時的問題。 隨著 fuchsia.git 的使用頻率增加,Rust 可能會發生衝突 流傳到其他花瓣的一小部分。 而且這類問題並不常見。

標準化演算法很簡單,但有一個難以察覺的失敗情況 - UPPER_SNAKE_CASE ID 中的混合英數字元 毀損。 例如 H264_ENCODERh264_encoderA2DP_PROFILEa2_dp_profile。 這是因為演算法會將數字視為小寫英文字母。 我們必須中斷數字轉字母,因為 H264Encoder 應該 標準化為 h264_encoder。 不含小寫英文字母的 ID 可以特殊大小寫,只有 會破壞底線,但這樣會增加演算法的複雜度 就好比心理模型

標準格式可以用字詞清單表示,而非 Low_camel_case 字串。 兩者完全相同,實際上是以字串形式管理比較容易。

我們可以使用 ID做為一般格式 這樣一來,這項破壞性變更就沒有明顯益處。 如果未來有情節重大的國旗日 請考慮變更

初步拒絕與第二次審查

這個 FTP 在 2019 年 4 月 18 日首次審查時,因下列內容遭拒: 理由。

  • 解決這類問題的兩方觀點。
  • 開始建立目標語言模型盡可能減少 即便與 FIDL 不同 建議樣式 這就是這套 FTP 採取的方法。
    • 優點:保有 Fuchsia 以外的最終 FIDL 使用彈性, 只擁有程式設計語言
    • 缺點:範圍規則較複雜,樣式未強制執行, 都鼓勵 (例如透過程式碼檢查) 可能會存取由不符合 Fuchsia 的合作夥伴建構的 API 我們想要的風格指南 (因為它們不需要執行,或是符合 程式碼檢查)。
  • 直接對語言強制執行樣式限制,即可消除 問題類別
    • 優點:落實風格、開發人員知道如何實踐 就無法編譯
    • 缺點:在語言定義中提示風格選項,高山 為使用 FIDL 的新手開發人員而設計
  • → 我們拒絕了提案,建議改用 並直接強制執行該語言的樣式
  • → 以下提供實現目標的正式提案,並具體說明 針對此的所有層面 (例如,uint8 應為 Uint8vector<T> 應為 Vector<T>?)

基於以下觀察結果,我們決定撤銷這項決策:

  • 核心 API 現在描述的是 FIDL。我們又重新開啟了 ID 獨特性問題,我們基本上撤銷了 也就是「C 型」和「FIDL-style」進而共存這是 就是今天的 fidl Linter 進行檢查

  • 我們已經看到其他可能推動 FIDL 一般傳輸作業的用途。 且當地樣式規則也可更妥善支援這些網域。

  • ID 不一致的問題依然存在,需要建立目標語言模型 也就是 FIDL 工具鍊中遺漏的限制條件。

既有藝術品和參考資料

在 proto3 中,類似規則是產生 lowerCamelCase 名稱, 。



  1. 直到新版 IR 結構定義為止,新版本的 IR 結構定義可能會沿用 避免提供現有完整名稱 今天。 

  2. 這個演算法已於 2020 年 6 月 3 日在接受 FTP 後 (順序) 修改。 以更貼近 FIDL 後端的現行行為