衡阳派盒市场营销有限公司

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Rust重寫的LSP:KCL IDE 插件的功能介紹與設計解析

jf_wN0SrCdH ? 來源:Rust語言中文社區 ? 2023-05-11 09:39 ? 次閱讀

在上周,KCL 發布了 v0.4.6 版本,這個版本在語言、工具鏈、社區集成&擴展支持等方面進行了重點更新。本文包含 KCL IDE 插件的功能特性和 LSP 的介紹、KCL LSP Server 端的設計和實現以及未來的規劃和期望。

功能特性

在這次更新中,我們發布了全新的 KCL VS Code 插件,并且用 Rust 重寫了 LSP 的 Server 端。我們提供了 IDE 中常用的代碼輔助功能,如高亮、跳轉、補全、Outline、懸停、錯誤提示等。

  • 高亮

fa1a0f0e-ef67-11ed-90ce-dac502259ad0.png

  • 補全

fa23ddea-ef67-11ed-90ce-dac502259ad0.png

  • Outline

fa4dc182-ef67-11ed-90ce-dac502259ad0.png

  • 懸停 & 跳轉

fa700efe-ef67-11ed-90ce-dac502259ad0.png

  • 錯誤/警告提示

fa7c9020-ef67-11ed-90ce-dac502259ad0.png

歡迎到 https://kcl-lang.io/docs/tools/Ide/vs-code/ 了解更多

什么是 LSP?

在這次更新中,我們基于 LSP 實現了以上能力。LSP 指的是 Language Server Protocol,它是由微軟在 2016 年推出的一種用于編程語言工具的協議。借用一張圖,很容易就可以理解 LSP。

fa96447a-ef67-11ed-90ce-dac502259ad0.pngLSP

通過 LSP ,編輯器和 IDE 可以通過 JSON-RPC 通信協議與后端運行的語言服務器(Server 端)進行通信。語言服務器可以提供代碼分析、自動補全、語法高亮、定義跳轉等功能。基于 LSP,開發者可以在不同的編輯器和 IDE 之間遷移,使得語言工具的開發從 M(語言數量) * N(編輯器/IDE數量) 降低為 M + N


為什么用Rust重寫?

KCL 編譯器和其他工具最初由 Python 實現,因為性能原因,我們用 Rust 語言重寫了編譯器(性能提升 40 倍!我們用 Rust 重寫了自己的項目)。在此之后,我們使用 Rust 逐步重寫了 KCL 的其他工具,如測試工具、Format 工具等。在這次更新中,我們用 Rust 重寫了 LSP Server 端,其主要考慮因素也是性能。

fa9fc9f0-ef67-11ed-90ce-dac502259ad0.png

過去,Python 版本的 Server 端在處理一些復雜的場景(編譯文件數量超過200個)時,處理一個跳轉的請求,Server 端從接收到請求到計算結果并響應,時間長達 6 秒以上,幾乎是不可用狀態。由于 Server 端的實現主要基于語言編譯器前中端的詞法解析和語義分析,在我們使用 Rust 重寫以后,這部分性能分別提升了 20 和 40 倍, 帶來的顯著結果就是 Server 端的響應時間得到了巨大提升,對于同樣的場景,響應時間縮短至 100 毫秒左右。而對于一些簡單的場景,響應時間只有幾毫秒,做到了用戶無感。

KCL LSP Server的設計與實現

KCL LSP Server 的設計如下圖所示:

fbda7824-ef67-11ed-90ce-dac502259ad0.png

主要流程可以分為幾個階段:

  1. 建立連接,初始化 LSP 能力。在 IDE 的 Client 端,打開特定文件(KCL的 *.k)時,IDE 會啟動本地的 kcl_language_server 二進制文件,啟動 Server 端。這個文件與 KCL 一起發布,并安裝在 KCL 的 bin 目錄下。Server 啟動后會建立 standard IO 的 Connection,并等待 Client 發送的初始化請求。Server 端接收初始化請求后會定義 Server 端信息和能力,并返回給 Client,以此完成 LSP 的初始化連接。
  2. 建立連接后,Server 端會啟動一個輪詢函數,不斷接收來自 Client 的 LSP Message,例如 Notification(打開/關閉/變更/刪除文件等)和 Request(跳轉、懸停等),以及來自 Server 端自身的 Task。并統一封裝成事件(Event)交給下一步處理。
  3. 對于各種事件,按照以下步驟處理:
///Handlesaneventfromoneofthemanysourcesthatthelanguageserversubscribesto.
fnhandle_event(&mutself,event:Event)->anyhow::Result<()>{
//1.Processtheincomingevent
matchevent{
Event::Task(task)=>self.handle_task(task)?,
Event::Lsp(msg)=>matchmsg{
lsp_server::Request(req)=>self.on_request(req,start_time)?,
lsp_server::Notification(not)=>self.on_notification(not)?,
_=>{}
},
};

//2.Processchanges
letstate_changed:bool=self.process_vfs_changes();

//3.HandleDiagnostics
ifstate_changed{
letmutsnapshot=self.snapshot();
lettask_sender=self.task_sender.clone();
//Spawnthediagnosticsinthethreadpool
self.thread_pool.execute(move||{
 handle_diagnostics(snapshot, task_sender)?;
});
}

Ok(())
}

3.1 任務分發:根據任務類型,做函數分發。在子函數中,會進一步基于 Request 或 Notification 的類型繼續分發到最終的處理函數中,如處理文件變更、處理跳轉請求等。這些函數會根據基于編譯器中前端編譯出的語義模型(AST,符號表,錯誤信息等)做分析,計算生成對應的 Response(如跳轉請求的目標位置)。

3.2 處理變更:用戶在修改代碼或更改文件時,會發送對應的 Notification。在前一步的處理中,會將變更保存在虛擬文件系統(VFS)中。Server 端會根據新的源代碼,進行重新編譯,保存新的語義模型,以供下一個請求做處理。

3.3 錯誤處理:這里的錯誤并非指 Server 端的運行錯誤,而是代碼編譯中的語法、語義錯誤,編譯警告等。Client 端并沒有對應的請求類型來請求這些錯誤,而是由 Server 端主動發送 Diagnostics。因此,在發生變更后,同步地將錯誤信息更新至 Client 端。

遇到的問題

1.為什么需要虛擬文件系統?

在最初的設計中,并沒有考慮使用虛擬文件系統。我們每次從文件系統中獲取源代碼,進行編譯和分析。對于一些“靜態”的任務,如跳轉,可以在變更代碼后保存到文件系統,然后再進行跳轉的操作。配合到 VS Code 的自動保存功能,體驗上并沒有明顯的差距。但對于代碼補全這一功能,IDE 中輸入的補全trigger(如 “.”)會觸發文件變更的通知和代碼補全的請求,但對應的代碼還未保存到文件系統中,編譯后的語義模型無法做對應的分析。因此,我們借助 Rust Analyzer 對應的 vfs 的create,在 Server 端引入了虛擬文件系統,將編譯的入口從文件路徑變為了 source code。Client 端輸入代碼后,文件變更的通知會先更新虛擬文件系統,重新編譯文件,生成新的語義模型,然后再處理補全請求。

2. 如何處理不完整的代碼?

我們遇到的另一個比較大的問題是如何處理不完整的代碼。同樣的,對于跳轉這類“靜態”的任務,可以假定代碼是完整、正確的。但對于補全操作,如以下代碼,希望在輸入.后,補全字符串的函數。對于編譯流程,第二行實際上是不完整的代碼,無法編譯出正常的 AST 樹。

s:str="hellokcl"
len=s.

為此,我們在 KCL 的編譯中實現了語法和語義上的多種錯誤恢復,保證編譯過程始終能產生完整的 AST 和符號表。在這個例子中,我們新增了一個表示空的 AST 節點作為占位符,使得第二行能夠生成完整的 AST。在處理補全的請求時,會根據 s 的類型和其他語義信息,補全函數名、schema attr 或 pkg 中定義的 schema 名。

Rust Analyzer architecture:

Architecture Invariant: parsing never fails, the parser produces (T, Vec) rather than Result.

總結與展望

KCL 的 IDE 插件目前已經實現高亮、跳轉、補全、Outline、懸停、錯誤提示等功能。這些功能提升了 KCL 用戶的開發效率。然而,作為一款 IDE 插件,它的功能還不夠完整。在未來的開發中,我們會繼續完善,未來的工作有以下幾個方向:

  1. 更多的語言能力:提供更多的功能,如代碼重構,錯誤的quick fix,代碼 fmt等,進一步完善功能,提升開發效率
  2. 更多的 IDE 接入:目前,KCL 雖然提供了 LSP,只接入了 VS Code,未來會基于 LSP 的能力為 KCL 用戶提供更多選擇。
  3. AI 能力的集成:目前,ChatGPT 風靡全網,各行各業都在關注。我們也在探索 AI×KCL 的結合,提供更智能的研發體驗。總之,我們會繼續完善和優化 KCL 的 IDE 插件,讓它更加成熟和實用。為KCL用戶帶來更加方便和高效的開發體驗。

審核編輯 :李倩


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 編程語言
    +關注

    關注

    10

    文章

    1950

    瀏覽量

    34989
  • LSP
    LSP
    +關注

    關注

    0

    文章

    13

    瀏覽量

    9822
  • KCL
    KCL
    +關注

    關注

    0

    文章

    8

    瀏覽量

    4102

原文標題:Rust 重寫的 LSP:KCL IDE 插件的功能介紹與設計解析

文章出處:【微信號:Rust語言中文社區,微信公眾號:Rust語言中文社區】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    Eclipse IDE插件研發工程師

    、 基于Eclipse IDE進行二次開發,將已有的工具鏈集成到Eclipse IDE中 。3、 根據需求開發新的功能插件。4、 解決開發過程中遇到的技術難點。崗位要求1、 計算機專業
    發表于 04-20 15:22

    IDE為S32 Design Studio安裝Lauterbach插件無法解析位置是為什么?

    我正在嘗試通過我的 IDE 為 S32 Design Studio 安裝 Lauterbach 插件無法解析位置。 ?
    發表于 06-08 06:01

    Rust代碼中加載靜態庫時,出現錯誤 ` rust-lld: error: undefined symbol: malloc `怎么解決?

    我正在 MCUXpresso IDE 中創建一個靜態庫。我正在使用 redlib 在我的代碼中導入 ` [i]stdlib.h`。它成功地構建了一個靜態庫。但是,靜態庫中未定義一些標準庫函數,例如
    發表于 06-09 08:44

    jquery插件寫法及用法(jQuery插件開發全解析

    如今做web開發,jquery 幾乎是必不可少的,同時jquery插件也是不斷的被大家所熟知,以及運用。最近在搞這個jquery插件,發現它的牛逼之處,所以講一講jQuery插件的寫法、使用jQuery
    發表于 12-03 09:21 ?1w次閱讀
    jquery<b class='flag-5'>插件</b>寫法及用法(jQuery<b class='flag-5'>插件</b>開發全<b class='flag-5'>解析</b>)

    用于MPLAB X IDE代碼性能分析插件的工作原理和代碼性能分析參考

    MPLAB X IDE提供收集有關C代碼函數的函數級性能分析(Function Level Profiling, FLP)數據的功能。但是,該數據無法在未安裝MPLAB X IDE插件
    發表于 06-11 04:28 ?11次下載
    用于MPLAB X <b class='flag-5'>IDE</b>代碼性能分析<b class='flag-5'>插件</b>的工作原理和代碼性能分析參考

    微軟開發基于Rust的新編程語言,將很快開源

    此前,微軟表示正探索將Rust作為C和C++的安全替代方案,并且也對外展示了使用Rust重寫Windows組件的體驗,根據微軟的說法,Rust是一種從根本上考慮安全性的編程語言,他們將
    的頭像 發表于 12-03 10:36 ?3960次閱讀

    用于MPLABX IDE的代碼性能分析插件

    MPLAB X IDE提供收集有關C代碼函數的函數級性能分析(Function Level Profiling,FLP)數據的功能。但是,該數據無法在未安裝MPLAB X IDE插件
    發表于 05-12 10:38 ?15次下載

    Rust重寫了自己的項目

    一年前,我們使用 Python 語言構建了整個 KCL 語言編譯器的實現,雖然在一開始的時候運行良好,Python 簡單易上手,生態豐富,團隊的研發效率也很高,但是隨著代碼庫的擴張和工程師人數的增加,代碼維護起來愈加困難。
    的頭像 發表于 02-02 16:45 ?1257次閱讀

    Cloudflare用Rust重寫Nginx C模塊,構建沒有Nginx的未來

    近日,Cloudflare 工程師介紹了如何使用 Rust 重寫基于 C 語言的 Nginx 模塊。Cloudflare 工程師在博客寫道,他們用 Rust 為 Cloudflare
    的頭像 發表于 03-08 09:36 ?804次閱讀

    Windows 11初嘗Rust,36000行內核代碼已重寫

    更早些時候,微軟用 Rust 重寫了 DirectWrite Core 庫的概念驗證,它是 Windows 的 DWrite 引擎的 Windows App SDK 實現,用于文本分析、布局和渲染
    的頭像 發表于 05-19 16:39 ?1056次閱讀
    Windows 11初嘗<b class='flag-5'>Rust</b>,36000行內核代碼已<b class='flag-5'>重寫</b>!

    用于Arduino IDE插件Blockly@rduino

    電子發燒友網站提供《用于Arduino IDE插件Blockly@rduino.zip》資料免費下載
    發表于 06-20 11:27 ?2次下載
    用于Arduino <b class='flag-5'>IDE</b>的<b class='flag-5'>插件</b>Blockly@rduino

    Rust構建QEMU插件的框架

    Cannonball 是一個用 Rust 構建 QEMU 插件的框架!您可以在 C 語言的 QEMU TCG 插件中執行的任何操作,都可以使用cannonball。編寫以最小的開銷和盡可能多的
    的頭像 發表于 07-21 16:57 ?967次閱讀

    JetBrains發布獨立Rust IDE:RustRover

    在推出 RustRover 之前,JetBrains 以插件形式在 IntelliJ IDEA 和 CLion 中支持 Rust 功能。現在他們開發多年的開源插件已成為 RustRov
    的頭像 發表于 09-18 16:47 ?1094次閱讀
    JetBrains發布獨立<b class='flag-5'>Rust</b> <b class='flag-5'>IDE</b>:RustRover

    一次Rust重寫基礎軟件的實踐

    受到2022年“谷歌使用Rust重寫Android系統且所有Rust代碼的內存安全漏洞為零” [1] 的啟發,最近筆者懷著濃厚的興趣也順應Rust 的潮流,嘗試著將一款C語言開發的基礎
    的頭像 發表于 01-25 11:21 ?701次閱讀

    SOLIDWORKS插件功能介紹 慧德敏學

    SOLIDWORKS擁有一系列內置及第三方插件,這些插件豐富了其功能并提高了設計效率。本文為您介紹SOLIDWORKS插件
    的頭像 發表于 11-23 15:56 ?532次閱讀
    百家乐最大的赌局| 百家乐官网投注网站是多少| 百家乐套路| 澳门百家乐官网赢钱秘| 大发888娱乐场zb8| 大赢家百家乐66| 百家乐官网赌假的工具| 威尼斯人娱乐城注册送彩金| 成都百家乐官网牌具| 网上百家乐官网追杀| 百家乐麻将牌| 百家乐官网规则| 云鼎百家乐官网现金网| 威尼斯人娱乐城开户地址| 百家乐官网喜牛| 花莲市| 机械手百家乐的玩法技巧和规则 | E世博百家乐的玩法技巧和规则 | 海尔百家乐官网的玩法技巧和规则 | 百家乐出庄几率| 百家乐官网开线| 皇冠网全讯通| 大众百家乐娱乐城| 百家乐玩法百科| 太阳城百家乐官网注册平台| 太阳城娱乐城官方网| 宝马会百家乐娱乐城| 澳门百家乐官网单注下| 乐九百家乐官网现金网| 大发888娱乐场下载地址| 百家乐讲谈| 择日自学24| 百家乐官网明灯| 阳新县| 大发888线上娱乐加盟合作| 破解百家乐游戏机| 百家乐官网制胜绝招| 冠军百家乐官网现金网| 高额德州扑克第七季| 91百家乐的玩法技巧和规则| 百家乐龙虎规则|