LanguageServer
IDE上のプログラミング補助機能(補完、情報提示など)をエディタごとに全言語分を作っていると大変だから、エディタと言語機能提供サーバを分けて実装しましょう。というのが基本概念です。
また、補助機能には言語解析がつきもので、パーシングに時間もかかることからプロセスを分けておくことでエディタの応答を犠牲にしないという効果も期待できます。
私が欲しかったのは補完機能なので、特にLanguageServerに拘る必要はなかったわけです。
しかし、後々わかったことですが、JavaScriptで書かれたパーサーがとんでもなく遅いということがあり、プロセスを分けることは重要と考え、最終的にLanguageServerで実装することにしました。
Language Server Protocol (LSP)
LanguageServerはプロトコルがLSPとして仕様化されています。
どのようなリクエストがクライアントから来ると、どのように応答しなければいけないというルールがAPIのレベル?で書かれています(実際は、jsonの生テキストのやり取りで実現しているのでしょうか)。
ですので、実装はCでもPythonでも何でも良いのです。
しかし、VSCodeに準備されているライブラリはNode.jsしかなかったため、今回はTypeScript実装としました。
世の中には様々なLanguageServerがあり、実装も様々であるようです。
補完機能とLanguageServer
VSCodeの補完機能は、インターフェースが発生させるイベント、マウスが単語の上に乗った(onHover)とか、補完キーワードが入力された(onCompletion)とかに対してそれをハンドルする処理を登録することで実現されます。
公式のページになんとなく書かれています。
このイベントハンドルは
- コールバック関数を登録する(拡張機能ローカルで応答する)
- LanguageServerに任せる(LanguageServer側で応答する)
が選べるようです。
こだわらないのであれば、実装もデバッグも楽なローカル実装をおすすめします。
LanguageServerの仕事
基本的に、以下の3つです。
- 何らかのタイミングでソースファイルをパース
- データベースを作る
- LSPリクエストに応じてデータベースから情報を精査して応答する
結構な種類のリクエストがありますが、全て実装しなくても問題ありません。
このページから実現したい機能をピックアップし、対応するLSPを調べ、それだけ実装することにします。
いずれにせよ、SystemVerilogのパーサーは必要です。