RiceCoder LSP Integration
Language Server Protocol (LSP) integration for RiceCoder, providing semantic code analysis, diagnostics, code actions, and hover information across multiple programming languages.
Overview
The ricecoder-lsp crate implements a Language Server Protocol server that enables semantic understanding of code. It provides:
- Semantic Analysis: Parse and analyze code structure for Rust, TypeScript, and Python
- Diagnostics: Generate errors, warnings, and hints for code issues
- Code Actions: Suggest fixes and refactorings for identified issues
- Hover Information: Display type information and documentation on hover
- Multi-Language Support: Extensible architecture for adding new languages
- Performance Optimization: Caching and performance tracking for efficient analysis
Features
Supported Languages
- Rust: Full semantic analysis with tree-sitter
- TypeScript: Full semantic analysis with tree-sitter
- Python: Full semantic analysis with tree-sitter
- Unknown Languages: Graceful degradation with basic analysis
Core Capabilities
- Symbol Extraction: Extract functions, types, variables, classes, and other symbols
- Import Tracking: Track dependencies and imports
- Diagnostic Generation: Identify syntax errors, style issues, and potential bugs
- Code Actions: Suggest fixes for common issues
- Hover Information: Display type information and documentation
- Caching: Cache parsed ASTs and symbol indexes for performance
- Performance Tracking: Monitor analysis time and resource usage
Architecture
┌─────────────────────────────────────────────────────────────┐
│ LSP Client (IDE) │
└────────────────────────┬────────────────────────────────────┘
│ LSP Protocol (JSON-RPC)
│
┌────────────────────────▼────────────────────────────────────┐
│ LSP Server (ricecoder-lsp) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ LSP Protocol Handler │ │
│ │ - Initialize/Shutdown │ │
│ │ - Document Synchronization │ │
│ │ - Request Routing │ │
│ └──────────────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Semantic Analysis Engine │ │
│ │ ┌────────────────┐ ┌────────────────┐ │ │
│ │ │ AST Parser │ │ Symbol Index │ │ │
│ │ │ - Rust │ │ - Lookup │ │ │
│ │ │ - TypeScript │ │ - References │ │ │
│ │ │ - Python │ │ - Definitions │ │ │
│ │ └────────────────┘ └────────────────┘ │ │
│ └──────────────────────────────────────────────────────┘ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Diagnostics & Code Actions │ │
│ │ - Issue Detection │ │
│ │ - Fix Suggestions │ │
│ │ - Code Transformations │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
API Documentation
LSP Server Interface
The main entry point for LSP functionality is the LspServer struct:
use LspServer;
// Create a new LSP server
let mut server = new;
// Run the server (handles stdio communication)
server.run.await?;
Key Methods:
new(): Create a new LSP server instancerun(): Start the server and handle client requestsstate(): Get the current server state (Initializing, Running, Shutdown)
Server Capabilities:
- Text document synchronization (full sync)
- Hover information
- Code actions
- Diagnostics
Semantic Analyzer Interface
The SemanticAnalyzer trait provides language-agnostic semantic analysis:
use ;
use Language;
// Create a Rust analyzer
let analyzer = new;
// Analyze code
let semantic_info = analyzer.analyze?;
// Extract symbols
let symbols = analyzer.extract_symbols?;
// Get hover information
let hover = analyzer.get_hover_info?;
Supported Analyzers:
RustAnalyzer: Rust code analysisTypeScriptAnalyzer: TypeScript code analysisPythonAnalyzer: Python code analysisFallbackAnalyzer: Fallback for unknown languages
Key Methods:
analyze(code: &str): Analyze code and extract semantic informationextract_symbols(code: &str): Extract all symbols from codeget_hover_info(code: &str, position: Position): Get hover information at a positionlanguage(): Get the supported language
Diagnostics Engine Interface
The DiagnosticsEngine trait generates diagnostics for code issues:
use ;
use Language;
// Create a diagnostics engine
let engine = new;
// Generate diagnostics
let diagnostics = engine.generate_diagnostics?;
// Generate diagnostics for a specific range
let range_diagnostics = engine.generate_diagnostics_for_range?;
Key Methods:
generate_diagnostics(code: &str, language: Language): Generate all diagnosticsgenerate_diagnostics_for_range(code: &str, language: Language, range: Range): Generate diagnostics for a specific range
Diagnostic Severity Levels:
Error: Critical issues that prevent compilationWarning: Potential issues that should be addressedHint: Style suggestions and improvements
Code Actions Engine Interface
The CodeActionsEngine trait suggests fixes for identified issues:
use ;
// Create a code actions engine
let engine = new;
// Get code actions for a diagnostic
let actions = engine.code_actions_for_diagnostic?;
// Apply a code action
let fixed_code = engine.apply_code_action?;
Key Methods:
code_actions_for_diagnostic(diagnostic: &Diagnostic): Get applicable code actionsapply_code_action(code: &str, action: &CodeAction): Apply a code action to code
Hover Provider Interface
The HoverProvider trait provides hover information:
use HoverProvider;
use Position;
// Create a hover provider
let provider = new;
// Get hover information
let hover = provider.hover_at?;
Key Methods:
hover_at(code: &str, position: Position): Get hover information at a position
Usage Examples
Example 1: Basic Semantic Analysis
use ;
let code = r#"
fn hello(name: &str) {
println!("Hello, {}", name);
}
"#;
let analyzer = new;
let semantic_info = analyzer.analyze?;
println!;
println!;
Example 2: Generating Diagnostics
use DefaultDiagnosticsEngine;
use Language;
let code = r#"
fn unused_function() {
let unused_var = 42;
}
"#;
let engine = new;
let diagnostics = engine.generate_diagnostics?;
for diagnostic in diagnostics
Example 3: Getting Hover Information
use HoverProvider;
use Position;
let code = r#"
let x: i32 = 42;
"#;
let provider = new;
let hover = provider.hover_at?;
if let Some = hover
Example 4: Applying Code Actions
use DefaultCodeActionsEngine;
use DefaultDiagnosticsEngine;
use Language;
let code = r#"
use std::collections::HashMap;
fn main() {
println!("Hello");
}
"#;
let diagnostics_engine = new;
let diagnostics = diagnostics_engine.generate_diagnostics?;
let actions_engine = new;
for diagnostic in diagnostics
Configuration
The LSP server can be configured via environment variables:
RICECODER_LSP_LOG_LEVEL: Set logging level (trace, debug, info, warn, error)RICECODER_LSP_CACHE_SIZE: Set cache size in MB (default: 100)RICECODER_LSP_TIMEOUT_MS: Set analysis timeout in milliseconds (default: 5000)
Performance
The LSP server is optimized for performance:
- Caching: Parsed ASTs and symbol indexes are cached for unchanged documents
- Incremental Analysis: Only re-analyze changed portions of code
- Performance Targets:
- < 500ms for files < 10KB
- < 2s for files < 100KB
- < 100ms for cached results
Error Handling
All operations return explicit error types:
use SemanticError;
match analyzer.analyze
Testing
The crate includes comprehensive tests:
- Unit Tests: Test individual components (analyzers, engines, providers)
- Integration Tests: Test end-to-end LSP workflows
- Property Tests: Verify correctness properties across all inputs
Run tests with:
Troubleshooting
Issue: Analysis is slow
Solution: Check cache hit rates and increase cache size if needed.
RICECODER_LSP_CACHE_SIZE=200
Issue: Unsupported language errors
Solution: The crate gracefully degrades for unsupported languages. Check logs for details.
RICECODER_LSP_LOG_LEVEL=debug
Issue: Diagnostics are missing
Solution: Ensure the language is correctly detected. Check language-specific rules.
let language = from_extension;
println!;
Contributing
When adding new features:
- Add language-specific analyzers in
src/semantic/ - Add diagnostic rules in
src/diagnostics/ - Add code actions in
src/code_actions/ - Add tests in
tests/ - Update this README with examples
Related Documentation
- Requirements:
.kiro/specs/ricecoder-lsp/requirements.md - Design:
.kiro/specs/ricecoder-lsp/design.md - Tasks:
.kiro/specs/ricecoder-lsp/tasks.md - LSP Specification: https://microsoft.github.io/language-server-protocol/
License
Part of the RiceCoder project. See LICENSE for details.