Sharpy LSP Server

View on GitHub

Overview

Sharpy includes a built-in Language Server Protocol (LSP) server, accessible via sharpyc lsp. The server is implemented in the Sharpy.Lsp project using OmniSharp.Extensions.LanguageServer, providing IDE features to any editor that supports LSP.

Architecture

The LSP server consists of three main layers:

  • SharpyWorkspace -- Manages document state (open files, edits, file versions). Tracks document content in memory and synchronizes with the compiler.
  • CompilerApi -- Provides analysis services (parsing, type checking, diagnostics) by invoking the Sharpy compiler pipeline on demand.
  • Handlers -- Implement individual LSP protocol methods, delegating to CompilerApi for analysis and returning results in the LSP wire format.
Editor <-> stdio (JSON-RPC) <-> LSP Server
                                  |
                                  +-- Handlers (one per LSP method)
                                  |     |
                                  |     +-- CompilerApi (analysis)
                                  |           |
                                  |           +-- Sharpy Compiler Pipeline
                                  |
                                  +-- SharpyWorkspace (document state)

Supported Features

Document Synchronization

MethodDescription
textDocument/didOpenTrack newly opened documents
textDocument/didChangeApply incremental edits
textDocument/didCloseRelease document state
textDocument/didSaveTrigger full re-analysis on save

Diagnostics

MethodDescription
textDocument/publishDiagnosticsPush compiler errors, warnings, and info to the editor

Diagnostics are published after each document change (debounced) and include all SPY-prefixed diagnostic codes from the compiler.

MethodDescription
textDocument/definitionGo-to-definition using Symbol.DeclarationSpan
textDocument/referencesFind all references using SemanticInfo reference tracking
textDocument/documentSymbolHierarchical document outline (classes, functions, variables)
textDocument/documentHighlightHighlight all occurrences of a symbol in the current document
workspace/symbolWorkspace-wide symbol search

Intelligence

MethodDescription
textDocument/hoverType information for identifiers, expressions, and function calls
textDocument/completionScope-aware, member, and type completion
textDocument/signatureHelpParameter hints during function calls
textDocument/inlayHintInferred type and parameter name annotations

Refactoring

MethodDescription
textDocument/renameSymbol rename with validation (rejects invalid names)
textDocument/codeActionQuick fixes for naming conventions, unused imports, unused variables

Display

MethodDescription
textDocument/semanticTokensSemantic highlighting (types, functions, parameters, etc.)
textDocument/foldingRangeCode folding for classes, functions, and block statements
textDocument/codeLensReference counts on symbols; run buttons for entry points
textDocument/formattingIndentation normalization

Transport

The LSP server communicates over stdio (stdin/stdout) using the JSON-RPC 2.0 protocol. This is the standard transport for LSP and works with all major editors.

sharpyc lsp

The server reads JSON-RPC messages from stdin and writes responses to stdout. Logging and diagnostics go to stderr.

Threading Model

  • Document map: ConcurrentDictionary<Uri, Document> for thread-safe document access
  • Per-document lock: SemaphoreSlim per document prevents concurrent analysis of the same file
  • Debounce: 300ms debounce on didChange events to avoid redundant re-analysis during rapid typing

Configuration

The server accepts configuration via the LSP workspace/didChangeConfiguration notification. Settings are typically configured through the editor (e.g., VSCode settings). See vscode-extension.md for the full settings reference.