New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
2022-07-24 #80
Comments
vscode-rubyに同梱されているlanguage-server-rubyという実装を読んでいる。
|
vscode-rubyは、複数のパッケージを扱うmonorepoとして管理されている。
monorepoの管理にはLernaを使っているとのこと。 |
language-server-rubyについて詳しく見ていく。 package.jsonを見ると、次のパッケージがdependenciesに含まれていた。
web- prefix付きなのが気になるが、確かにtree-sitterが使われている。 package.jsonのmainフィールドにdist/index.jsとあり、npm run buildではesbuild.jsが利用されている。 esbuild.jsの中では、web-tree-sitter-ruby/tree-sitter-ruby.wasmが参照されている。 |
language-server-rubyのesbuild.jsを見ると、次の二つのことをやっているのが分かる。
language-server-rubyのエントリポイントがsrc/index.jsであることが分かったので、ここを読み進めていく。 |
esbuildを使うのは初めてだけど、こういう感じで使うんだなあ。
と実行するというのが面白い。普通だったらオプションとかを渡したくなってCLIオプションを付けるためにCLIを用意するものだけど、esbuildの場合はどうせ設定ファイルを用意することになるので、そういうものを用意する必要は無いわという判断なのだろうか。まあ無くて良いなら無いに越したことはない。 |
// Don't die when attempting to pipe stdin to a bad spawn
// https://github.com/electron/electron/issues/13254
process.on('SIGPIPE', () => {
log.error('SIGPIPE received');
}); とあり、そういえばVS CodeはElectronベースだから、Electronの不具合の影響を受けるんだったと思い出した。 |
基本のlanguage serverの実装はこういう感じのようだ。 import { createConnection, ProposedFeatures } from "vscode-languageserver";
cosnt connection = createConnection(ProposedFeatures.all);
// Customize connection as you like...
connection.listen(); |
let server;
connection.onInitialize(async (params) => {
server = new Server(connection, params);
server.initialize();
return server.capabilities;
}); こんな感じのコードが書かれているから、実際には なので、読むべきは次の実装:
capabilitiesというのは、「このlanguage serevrはDocumentHighlightに対応ています」のような情報を明示するためのオブジェクトらしい。 |
language-server-rubyでは、VS Codeの拡張として提供する各機能の単位を "Provider" と呼称しているようだ。VS Codeの用語なのか独自用語なのかはわからない。 language-server-rubyでは、次の6つのProviderを用意しているようだ。
前者4つは初期化フェーズ中に用意され、後者2つは初期化フェーズ完了後に用意される。connection.onInitializeとconnection.onInitializedでそれぞれ用意されている。
でそれぞれ実装されているが、このネーミングは少し分かりづらい…
とかで良かっただろうと思う。 その話はさておき、Server.tsの主な仕事はこのようにProviderを用意してあげることらしく、主な実装はつまりそれぞれのProviderに書かれているに違いない。 Providerは、初期化時にconnectionを受け取って、何か良い感じに動くもののようだということが分かっている。 |
各種Providerは基底Providerクラスを継承しているらしい。 |
Connection#onDocumentHighlight という、コールバック登録用のメソッドが生えているらしいDocumentHighlightProviderはこれをそのconstructorで呼び出している。ググってもonDocumentHighlightに関する情報は乏しい…… onDocumentHighlightに渡す引数はServerRequestHandler型で、実際のコード例を見ると、TextDocumentPositionParams型の引数を取るらしい。位置情報が与えられるので、それに応じて何か適切に動作しろということだろうか。 paramsはpositionとuriを持つObjectらしい。多分ファイルパスとその中での位置情報が入っている。 DocumentHighlightAnalyzer.analyze にこれらの値を渡してその返り値をそのまま返している。役割分担を整理するとこうだ:
|
DocumentHighlightAnalyzerでは、tree-sitterを利用した構文の解析と、
tree-sitter-rubyの生成する構文木の実例を見ながら進めていった方が分かりやすいかもしれない。 vscodeの "document highlight" という機能・概念を正確にするため、ぐぐってみた方が良さげ。
いろいろ調べていると、次のような言及があった。
|
今回はvscode-rubyの読書メモを書き連ねていきます。
The text was updated successfully, but these errors were encountered: