Skip to content
CAI
Software that uses CAICheck a score

razzmatazz/csharp-language-server

53.1

Adequate · 23 September 2026

22.2k

lines of production code

F#

primary language

5

measurements over time

CAI band scale
CAI trend line
CAI lens gauges

What this system is

This system is a C\# Language Server (csharp-ls) that provides IDE features such as code completion, diagnostics, and navigation by integrating with the Roslyn compiler platform. It implements the Language Server Protocol (LSP) to communicate with editors, supporting capabilities like semantic highlighting, call hierarchy, and code actions. The project is built in F\# on .NET 10 and includes tooling for reproducible development and automated code formatting.

How it got here

2020 — Nix integration and LSP modernization

4 changes.

The project underwent a significant infrastructure overhaul by introducing Nix support for reproducible development and migrating the LSP implementation to the fsac/LanguageServerProtocol library. Concurrently, the codebase was upgraded to .NET 10 and Roslyn 5.9.0, with centralized package management and enhanced diagnostic logging added to improve maintainability and tooling compatibility.

2021–2024 — C\# language server implementation

5 changes.

This period focused on building the core C\# language server, introducing LSP handlers for features like completion, code actions, and call hierarchy, alongside a robust workspace state machine. The work also included migrating the JSON-RPC transport to System.Text.Json and establishing a stable, pooled test infrastructure to ensure comprehensive coverage and reliable CI execution.

2025–2026 — LSP 3.17 upgrade and analyzer integration

4 changes.

The project upgraded its Language Server Protocol support to version 3.17.0, introducing a new MetaModelGenerator tool and switching to System.Text.Json for serialization. Concurrently, the C\# language server was enhanced with Roslyn Analyzer integration for richer diagnostics and improved performance through optimized solution parsing. Development hygiene was also strengthened by enforcing F\# code formatting via a Fantomas pre-commit hook.

Features

Introduce MetaModelGenerator tool for LSP type generation

Added the MetaModelGenerator tool, which generates F\# types for the Language Server Protocol. The generator uses System.Text.Json for serialization (replacing Newtonsoft.Json) and includes logic to handle LSPAny as JsonElement, merge structure-literal unions into single optional-record types, and apply custom DebuggerDisplay attributes to Range, Position, and Diagnostic records.

MetaModelGenerator · high confidence

Introduce diagnose command and configurable logging

The C\# Language Server now includes a \--diagnose\ command to help troubleshoot environment and configuration issues, and adds a \--log-level\ argument to control verbosity (defaulting to \info\). Logging is now handled via Microsoft.Extensions.Logging, which forwards trace messages to the LSP client and includes timestamps in console output.

src/CSharpLanguageServer · high confidence

New C\# metadata and call hierarchy handlers

The language server now supports viewing source code for generated documents and decompiled metadata symbols via the new CSharpMetadata handler, and provides call hierarchy navigation (incoming and outgoing calls) via the CallHierarchy handler, which also counts constructor initializers as outgoing calls.

src/CSharpLanguageServer/Handlers · high confidence

New LSP handler implementations and workspace state management

This change introduces the core implementation files for the C\# language server's LSP handlers and workspace management. It adds new modules for CodeAction, CodeLens, Completion, and SignatureHelp, providing the logic for features like code fixes, symbol references, IntelliSense, and parameter hints. It also introduces the Lsp.Workspace and Lsp.WorkspaceFolder modules, which define the new state machine for workspace phases (Uninitialized, Configured, Loading, Ready, Reconfiguring, ShuttingDown) and manage folder-level solution loading and updates. Additionally, DocumentationUtil.fs is added to handle the parsing and formatting of XML documentation comments for hover and signature help.

CSharpLanguageServer · high confidence

Project restructured with Nix support and standardized development environment

The repository has been reorganized to include a Nix flake for reproducible development, a global.json pinning the .NET SDK to version 10.0.100, and an .editorconfig enforcing consistent code style (UTF-8, LF line endings, 120-character max line length). The solution file was updated to reflect the new project layout, including the test project, and a .gitignore was added to exclude common IDE and build artifacts.

(repo-wide) · high confidence

Behavioural changes

Enforces F\# code formatting via Fantomas pre-commit hook

A new pre-commit hook has been added to the .githooks directory to automatically check that staged F\# files (.fs, .fsi, .fsx) are formatted according to Fantomas standards. This ensures consistent code style before commits are finalized, excluding the vendored Ionide.LanguageServerProtocol directory. Developers must have the dotnet fantomas tool installed and configured via core.hooksPath to benefit from this check.

.githooks · high confidence

Language Server Protocol support updated to version 3.17.0

The Ionide.LanguageServerProtocol library has been updated to support LSP specification version 3.17.0. This update imports the new metaModel and schema definitions for version 3.17.0, adding support for new protocol features such as notebook document synchronization (open, change, save, close), type hierarchy (prepare, supertypes, subtypes), and various refresh requests for semantic tokens, inlay hints, code lenses, inline values, and diagnostics. The library also switches its JSON serialization from Newtonsoft.Json to System.Text.Json for the active code path, while keeping the legacy Newtonsoft/StreamJsonRpc path disabled by default to reduce dependencies.

Ionide.LanguageServerProtocol, src/Ionide.LanguageServerProtocol · high confidence

Migrate LSP client transport and progress reporting to System.Text.Json

The LSP client implementation in src/CSharpLanguageServer/Lsp/Client.fs has been rewritten to use System.Text.Json for serializing and deserializing JSON-RPC messages, replacing the previous Newtonsoft.Json-based transport. This change includes a new ProgressReporter component that correctly respects the client's window.workDoneProgress capability, ensuring progress notifications are only sent when supported. The server-side handler registration in Server.fs now utilizes this new client interface and sanitizes completion item resolve parameters using System.Text.Json before processing.

src/CSharpLanguageServer/Lsp · high confidence

Migrate LSP implementation to fsac/LanguageServerProtocol

The \src/LSP\ directory has been refactored to use the \fsac/LanguageServerProtocol\ library, replacing the previous custom-built LSP infrastructure. This change removes the internal modules responsible for manual JSON serialization and deserialization (\Ser.fs\), message parsing (\Parser.fs\), tokenization (\Tokenizer.fs\), logging (\Log.fs\), and document state management (\DocumentStore.fs\). By adopting the standard library, the language server now relies on external abstractions for handling LSP protocol details, simplifying the codebase and ensuring compatibility with standard LSP tooling.

src/LSP · high confidence

Support for Roslyn Analyzers and improved diagnostics handling

The C\# language server now integrates with Roslyn Analyzers to provide richer code analysis and diagnostics. A new \Analyzers.fs\ module manages shared project analysis results and caches them per solution snapshot, ensuring that both compiler and analyzer diagnostics are collected efficiently. The \Document.fs\ module has been updated to handle document formatting options, including end-of-file newline normalization, while \Conversions.fs\ adds support for mapping source-generated documents to LSP locations. Additionally, \Solution.fs\ improves target framework resolution by parsing project XML directly when possible to avoid unnecessary MSBuild invocations, and \Symbol.fs\ refines metadata name generation to prevent crashes on certain symbol types.

src/CSharpLanguageServer/Roslyn · high confidence

Test coverage

Expanded test coverage for C\# language server features; Stabilized test infrastructure with pooled LSP clients and expanded test coverage.

Dependencies

Upgrade to .NET 10 and Roslyn 5.9.0 with Central Package Management

The C\# language server has been upgraded to target .NET 10.0 and utilizes Roslyn 5.9.0, enabling support for the latest .NET runtime features and C\# language capabilities. The project now implements Central Package Management (CPM) via a new Directory.Packages.props file to standardize dependency versions across the solution. Additionally, the legacy LSP module has been removed in favor of the Ionide.LanguageServerProtocol library, and the tool is now packaged as a distributable .NET tool named csharp-ls.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Score

  • CAI 54 → 53 (-0.9)
  • Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.

Lenses

  • Code Health 80 → 69 (-11.1)
  • Architecture 53 → 37 (-16.1)
  • Maturity 61 → 62 (+0.5)
  • Readiness 50 → 75 (+25.2)
  • Security 57 → 83 (+26.3)

Resolved (55)

  • Diagnostic.getWorkspaceDiagnosticReports (cyclomatic 19) (src/CSharpLanguageServer/Handlers/Diagnostic.fs)
  • Duplicated block (10 lines × 2) (src/CSharpLanguageServer/Handlers/DocumentOnTypeFormatting.fs)
  • Duplicated block (10 lines × 2) (src/CSharpLanguageServer/Handlers/DocumentSymbol.fs)
  • Duplicated block (10 lines × 2) (src/CSharpLanguageServer/Handlers/SignatureHelp.fs)
  • Duplicated block (10 lines × 3) (src/CSharpLanguageServer/Handlers/InlayHint.fs)
  • Duplicated block (11 lines × 2) (src/CSharpLanguageServer/Handlers/CodeAction.fs)
  • Duplicated block (11 lines × 2) (src/Ionide.LanguageServerProtocol/src/LanguageServerProtocol.fs)
  • Duplicated block (12 lines × 2) (src/Ionide.LanguageServerProtocol/tools/MetaModelGenerator/GenerateClientServer.fs)
  • Duplicated block (13 lines × 2) (src/CSharpLanguageServer/Handlers/TypeHierarchy.fs)
  • Duplicated block (13 lines × 2) (src/CSharpLanguageServer/Roslyn/Conversions.fs)
  • Duplicated block (15 lines × 2) (src/CSharpLanguageServer/Roslyn/Conversions.fs)
  • Duplicated block (18 lines × 2) (src/Ionide.LanguageServerProtocol/src/JsonRpc.fs)
  • Duplicated block (21 lines × 6) (src/Ionide.LanguageServerProtocol/src/Types.cg.fs)
  • Duplicated block (24 lines × 2) (src/Ionide.LanguageServerProtocol/src/Types.cg.fs)
  • Duplicated block (35 lines × 2) (src/Ionide.LanguageServerProtocol/src/Types.cg.fs)
  • Duplicated block (39 lines × 2) (src/Ionide.LanguageServerProtocol/src/Types.cg.fs)
  • Duplicated block (7 lines × 2) (src/CSharpLanguageServer/Handlers/DocumentSync.fs)
  • Duplicated block (8 lines × 2) (src/CSharpLanguageServer/Roslyn/Conversions.fs)
  • Duplicated block (8 lines × 3) (src/CSharpLanguageServer/Handlers/CodeLens.fs)
  • Duplicated block (8 lines × 3) (src/CSharpLanguageServer/Handlers/DocumentFormatting.fs)
  • …and 35 more

New (57)

  • CallHierarchy.outgoingCalls (cognitive 50) (src/CSharpLanguageServer/Handlers/CallHierarchy.fs)
  • CallHierarchy.outgoingCalls (cyclomatic 20) (src/CSharpLanguageServer/Handlers/CallHierarchy.fs)
  • Duplicated block (10 lines × 2) (src/CSharpLanguageServer/Handlers/DocumentSymbol.fs)
  • Duplicated block (10 lines × 3) (src/CSharpLanguageServer/Handlers/DocumentSync.fs)
  • Duplicated block (10 lines × 3) (src/CSharpLanguageServer/Handlers/InlayHint.fs)
  • Duplicated block (11 lines × 2) (src/CSharpLanguageServer/Handlers/CodeAction.fs)
  • Duplicated block (11 lines × 2) (src/CSharpLanguageServer/Handlers/DocumentOnTypeFormatting.fs)
  • Duplicated block (11 lines × 2) (src/CSharpLanguageServer/Handlers/SignatureHelp.fs)
  • Duplicated block (11 lines × 2) (src/Ionide.LanguageServerProtocol/tools/MetaModelGenerator/GenerateClientServer.fs)
  • Duplicated block (11 lines × 2) (src/Ionide.LanguageServerProtocol/tools/MetaModelGenerator/GenerateTypes.fs)
  • Duplicated block (11–13 lines × 2) (src/CSharpLanguageServer/Handlers/TypeHierarchy.fs)
  • Duplicated block (12 lines × 2) (src/CSharpLanguageServer/Roslyn/Conversions.fs)
  • Duplicated block (13 lines × 2) (src/Ionide.LanguageServerProtocol/src/JsonUtils.fs)
  • Duplicated block (14 lines × 2) (src/CSharpLanguageServer/Handlers/CallHierarchy.fs)
  • Duplicated block (15 lines × 2) (src/CSharpLanguageServer/Roslyn/Conversions.fs)
  • Duplicated block (16 lines × 7) (src/Ionide.LanguageServerProtocol/src/Types.cg.fs)
  • Duplicated block (24 lines × 6) (src/Ionide.LanguageServerProtocol/src/Types.cg.fs)
  • Duplicated block (24–33 lines × 2) (src/Ionide.LanguageServerProtocol/src/Types.cg.fs)
  • Duplicated block (43 lines × 2) (src/Ionide.LanguageServerProtocol/src/Types.cg.fs)
  • Duplicated block (7 lines × 2) (src/CSharpLanguageServer/Handlers/Workspace.fs)
  • …and 37 more

Changes since last survey

  • 91 commits — 71 feature/other, 20 fixes

By area

  • tests/CSharpLanguageServer.Tests — 48 commits
  • (root) — 21 commits
  • src/CSharpLanguageServer — 10 commits
  • .github/workflows — 5 commits
  • src/Ionide.LanguageServerProtocol — 3 commits
  • plans/razor-sdk-300-investigation.md — 2 commits
  • plans/interactive-request-latency-vs-analyzers.md — 1 commit
  • plans/system-text-json-migration.md — 1 commit

Notable commits

  • fix: Add regression test for Central Package Management project loading
  • fix: Re-enable Razor tests: upgrade Roslyn to 5.9.0 and fix hover/reference token mapping
  • fix: Revert "ci(test): cap concurrent LSP clients instead of halving Windows test workers" and "ci: run Windows tests with a single worker to reduce flakiness"
  • fix: Revert "test(internal): migrate InternalTests.fs from NUnit to Expecto", "test(ci): run NUnit and Expecto suites separately via new Makefile", "fix(makefile): stop generating EXPECTO_EXCLUDE_FILTER via subst/foreach"
  • fix: chore: add CHANGELOG.md entry for Windows uri casing fix
  • fix: fix(callhierarchy): anchor fromRanges at the callee name token
  • fix: fix(callhierarchy): group constructed generic targets by original definition
  • fix: fix(fixturepool): decouple boot IO from the pool actor to prevent CI hangs
  • fix: fix(fixturepool): unify pooled and ad-hoc client admission to fix CI deadlock
  • fix: fix(makefile): stop generating EXPECTO_EXCLUDE_FILTER via subst/foreach
  • fix: fix(references): resolve metadata locations against the symbol's own project
  • fix: fix(solution): honor .slnf filters in the declared-project set
  • fix: fix(tests): kill a timed-out dotnet build before reading its output
  • fix: fix(tests): stop MSBuild stragglers from holding the build's output pipes
  • fix: fix(workspace): match request uris to workspace folders case-insensitively on Windows
  • fix: fix(workspace): only force a TargetFramework every project declares
  • fix: fix(workspace): resolve multi-targeted project documents to a best-TFM flavor
  • fix: fix(workspace): reuse one ProxyGenerator across GetService interceptions
  • fix: fix(workspace): serialize ProxyGenerator access to fix CI test hangs
  • fix: test: remove [<Retry>] from all tests, fix the real races it hid
  • …and 71 more

Architecture

  • Containers 0 added · 0 removed · contexts 4 added · 0 removed · edges 3 added · 0 removed

Added bounded contexts (4)

  • CSharpLanguageServer
  • CSharpLanguageServer.Tests
  • Ionide.LanguageServerProtocol
  • MetaModelGenerator

Added dependency edges (3)

  • CSharpLanguageServer → Ionide.LanguageServerProtocol (coupling)
  • CSharpLanguageServer.Tests → CSharpLanguageServer (coupling)
  • CSharpLanguageServer.Tests → Ionide.LanguageServerProtocol (coupling)

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

razzmatazz/csharp-language-server was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 23 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit 72671fc7fa810c158864e72485db68e8b9b25c3d — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-955b9cee9818.