Abandon TypeProf.wasm + LSP Integration for Ruby Code Completion #59
takaokouji
started this conversation in
ADR (Any Decision Record)
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Abandon TypeProf.wasm + LSP Integration for Ruby Code Completion
Sorry, this is written in Japanese.
Rubyタブのコード補完に TypeProf.wasm + LSP を採用しない
Issue #166(Rubyタブの入力補助の再構築)の課題4・段階3として、TypeProf.wasm を Web Worker で動かし
monaco.lspAPI で Monaco Editor と接続する実装にチャレンジした。実装内容は smalruby/smalruby3-editor#171(sub-issue)および smalruby/smalruby3-editor#172(実装PR)に記録されている。
実装後の動作検証の結果、TypeProf による補完の恩恵がほとんど得られないことが判明したため、この方向性を中止する。
判断基準や制限
選択肢
決定
採用: 採用せず、段階1+段階2で完結させる
move(10)やturn_right(15)のようにレシーバーなしのメソッド呼び出しがほとんどであり、prefix 補完(識別子の途中入力)には対応していないため、実質的な恩恵がない各選択肢の良い点と悪い点
TypeProf.wasm + LSP によるコード補完を採用する
+型情報に基づく高精度な補完が期待できる+.や::トリガーでのメソッド補完が動作する("hello".→ String メソッド一覧 など)-スモウルビーのプログラムはレシーバーなしのメソッド呼び出しがほとんどであり、TypeProf の prefix 補完非対応が致命的movと入力してもmove(10)の候補が出ない./::)でのみ補完候補を返す設計(service.rb:completionのnode.code_range.last == pos.rightチェック)-ファイル数・コード量が増大し複雑度が上がるtypeprof-worker.js,typeprof-bootstrap.rb,smalruby.rbs,typeprof-lsp-client.js等が追加(+555行/-8行)-入力中の構文エラーが多発し、Monaco のエラー表示がノイズになるmove()で TypeProf が構文エラー診断を送出し、赤波線が頻繁に発生-Monaco 言語 ID をsmalruby(カスタム)からruby(組み込み)に変更する必要があり、既存の設定(インデントルール等)との競合が生じたruby組み込み言語設定をロードし、カスタムsetLanguageConfigurationを上書きする問題が発生when_flag_clickedのようなwhen_プレフィクスのメソッドが誤ってデデントされるバグが再発-LSP 関連の依存(monaco.lspAPI)が不安定。Monaco Editor 開発者自身が「バグがある可能性がある」と明言している-Jest テスト環境でfile:///URI スキームの扱いに追加対応が必要になるなど、テスト環境コストが増加-Web Worker での TypeProf.wasm 初期化に数秒かかるため、エディタ起動時の体験が低下する-ruby.wasmバイナリが 53MB と大きく、.gitignoreに追加してダウンロードスクリプトで取得する運用が必要採用せず、段階1+段階2で完結させる
+コードベースがシンプルに保たれる+既存の補完品質(スニペット補完 + コンテキスト判定)をそのまま維持できる+スモウルビーの主要ユースケース(レシーバーなしのメソッド補完)はスニペット補完で十分カバーされている-TypeProf の型情報を活用した高精度補完は得られない-./::トリガーでのメソッド補完(例:"hello".lengthなど)は実装されない付録: 実装過程で判明した技術的知見
アーキテクチャ(実装済み状態)
実装過程で遭遇した課題と対処
課題1:
url_schemaの誤設定url_schema: "file:///"(スラッシュ3個) ではuri_to_pathが"file:///workspace/main.rb"から"workspace/main.rb"(相対パス) を生成してしまい、TypeProf がtextDocument/didOpenをスキップする。url_schema: "file://"(スラッシュ2個) が正しく、/workspace/main.rb(絶対パス) を生成する。課題2:
publish_all_diagnosticskwargRubox のコードをベースにすると
publish_all_diagnostics: trueが含まれるが、TypeProf 本体のinitializeはurl_schema:のみ受け付けるため ArgumentError になる。課題3:
smalruby.rbsの内容が空webpack の
DefinePlugin.runtimeValueでtypeprof-bootstrap.rbとsmalruby.rbsを読み込み、__SMALRUBY_RBS_PLACEHOLDER__トークンを実際の RBS 内容で置換する方法で解決した。ただしwebpack.config.jsの変更は HMR では反映されないため、dev サーバーの再起動が必要。課題4: Monaco モデルの言語 ID
MonacoLspClientはdocumentSelectorが undefined の場合、Monaco の組み込み言語(ruby)にのみプロバイダを自動登録する仕様。カスタム言語smalrubyではcapabilities._staticCapabilitiesが{}のままでプロバイダが登録されず、補完リクエストが Worker に届かない。monaco.languages.register({id: 'smalruby'})を廃止し、language="ruby"に変更することで解決した。ただし後述の問題が発生。課題5: Monaco CDN による言語設定の上書き
Monaco は組み込み言語(
ruby)の設定を CDN から非同期にロードする。この非同期ロードがhandleEditorDidMount後に実行され、setLanguageConfiguration('ruby', smalrubyLanguageConfiguration)を上書きしてしまう。上書きされた
decreaseIndentPatternは(end|rescue|ensure|else|elsif|when)\bとなり、when_flag_clickedのようなwhen_プレフィクスのメソッド名を誤ってデデントする。smalrubyLanguageConfigurationのdecreaseIndentPatternではwhen\s(スペース必須)としてwhen_xxxを除外しているが、CDN ロード後に上書きされると無効化される。monaco.languages.onDidChangeでlanguageId === 'ruby'の変更を検知し再適用する方法を検討したが、monaco.languages.onDidChange is not a functionエラーが発生した(monaco-editor 0.55.1 では API が存在しない)。課題6: TypeProf の identifier prefix 補完非対応
TypeProf の
service.rb:completionメソッドはnode.code_range.last == pos.rightで補完位置をチェックする。これは「カーソルがAST ノードの末尾」のときのみ補完候補を返すため、movのような識別子入力中には候補を返さない。ドット補完(
"hello".)は動作する。これはメソッドチェーン呼び出しノードの末尾がカーソル位置と一致するため。課題7: Smalruby メソッドのコンテキスト(RBS での対処)
TypeProf は
main.rbのselfをObjectと解釈するため、SmalrubySpriteのメソッドは補完されない。smalruby.rbsにclass Objectを追加して全 Smalruby メソッドをトップレベルで定義することで"undefined method: Object#mov"の診断は解消できた。ただし prefix 補完非対応の問題は解消されない。動作確認済み状態
def/doブロック外)when_def/doブロック外)movdo...end内mov動かす move(10)等 139件do...end内"hello".スニペット補完が
do...end内で正しく動作しており、TypeProf の恩恵はドット補完のみ。スモウルビーのユースケースでドット補完が必要なケースはほぼない。参考: 調査対象
monaco.lspAPI(実験的)Beta Was this translation helpful? Give feedback.
All reactions