なぜ SharpLsp で F# が一等市民なのか
SharpLsp チーム
Nimblesite エンジニアリング
SharpLsp は C# と F# のための .NET 言語サーバーです。この表現は意図的なものです。F# は将来の互換性メモでも、統合の後付けでも、C# の横のチェックボックスでもありません。
F# の一等サポートは、最初から言語サーバーのアーキテクチャに設計されていなければなりません。プロジェクトモデル、リクエストルーティング、テスト戦略、エディター UX がすべて最初から C# を中心に構築されると、F# は最終的に他人の前提条件に対する脆弱なアダプターになります。
SharpLsp は、F# に独自のセマンティックサイドカーと LSP ホストでの同等の地位を与えることでこれを回避します。
F# のツール要件は異なります
F# は構文が異なる C# ではありません。コンパイラーパイプライン、ファイル順序のルール、インタラクティブワークフロー、シグネチャファイル、パイプライン重視のコードスタイル、型推論のエルゴノミクスはすべて言語固有の処理が必要です。
これは通常のエディターの動作に影響します。
- プロジェクトファイルの順序がコンパイルに重要です。
- ホバーと補完では、推論された型が明確に表示される必要があります。
.fs、.fsx、.fsiファイルには異なるワークフローが必要です。- F# Interactive はオマケではなく、コアな開発ループです。
- フォーマッターとアナライザーの期待は C# とは異なります。
本格的な .NET LSP はこれらの違いを尊重しながら、共有が有益な場所では共有インフラストラクチャーを活用する必要があります。
SharpLsp のサイドカーモデル
SharpLsp は共有 LSP 動作のために Rust ホストプロセスを使用し、セマンティック言語作業をコンパイラーベースのサイドカーに委任します。
- C# のセマンティックリクエストは Roslyn サイドカーに向かいます。
- F# のセマンティックリクエストは FSharp.Compiler.Service サイドカーに向かいます。
- ホストはルーティング、キャンセル、ワークスペース通知、サイドカーのライフサイクル、エディタープロトコルの動作を所有します。
これにより、各言語は必要なコンパイラーサービスを取得でき、SharpLsp を 2 つの無関係な製品に分割することなく実現します。共有ホストは、ひとつのインストール場所、ひとつの sharplsp エントリポイント、ひとつのプロトコルサーフェス、ひとつのエディター統合ストーリーなど、共通の動作を引き続き強制できます。
一等市民とは実際にどういうことか
SharpLsp にとって、F# の一等サポートとは .fs ファイルをクラッシュせずに開くこと以上を意味します。F# 機能には独自の受け入れ基準が必要です。
- F# プロジェクトは F# 対応のプロジェクト評価を通じてロードされます。
- F# 診断は FSharp.Compiler.Service と F# アナライザーから来ます。
- F# のホバー、補完、定義、参照、リネーム、コードアクションは実際の言語機能として追跡されます。
- F# Interactive コマンドはエディターワークフローとして公開されます。
- C# パスが通過するからといって F# のテストカバレッジをオプションとして扱いません。
共有 .NET ツールも重要です
一等市民であることは孤立を意味しません。C# と F# プロジェクトは同じソリューション内に共存することが多いです。開発者は依然として、ひとつの Solution Explorer、ひとつのビルドストーリー、ひとつのデバッガーパス、ひとつのプロファイラー、ひとつのパッケージ管理サーフェスを必要としています。
SharpLsp の仕事は、これらの共有ワークフローを一貫して感じさせながら、言語固有のコンパイラーサービスに言語固有の質問に答えさせることです。
これが本物のオープンソース .NET IDE バックエンドの形です。エコシステムが共有されている場合は共有インフラストラクチャー、正確さが要求する場合は専用の言語サービス。
基準
SharpLsp の F# サポートは、F# 開発者が C# 製品のゲストであると感じることなく SharpLsp を日常のツールとして使用できるまで完成しません。
それが SharpLsp が目指している基準です。