ricecoder-lsp 0.1.71

Language Server Protocol integration for RiceCoder
Documentation
# 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:

```rust
use ricecoder_lsp::LspServer;

// Create a new LSP server
let mut server = LspServer::new();

// Run the server (handles stdio communication)
server.run().await?;
```

**Key Methods**:

- `new()`: Create a new LSP server instance
- `run()`: Start the server and handle client requests
- `state()`: 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:

```rust
use ricecoder_lsp::semantic::{SemanticAnalyzer, RustAnalyzer};
use ricecoder_lsp::types::Language;

// Create a Rust analyzer
let analyzer = RustAnalyzer::new();

// Analyze code
let semantic_info = analyzer.analyze(code)?;

// Extract symbols
let symbols = analyzer.extract_symbols(code)?;

// Get hover information
let hover = analyzer.get_hover_info(code, position)?;
```

**Supported Analyzers**:

- `RustAnalyzer`: Rust code analysis
- `TypeScriptAnalyzer`: TypeScript code analysis
- `PythonAnalyzer`: Python code analysis
- `FallbackAnalyzer`: Fallback for unknown languages

**Key Methods**:

- `analyze(code: &str)`: Analyze code and extract semantic information
- `extract_symbols(code: &str)`: Extract all symbols from code
- `get_hover_info(code: &str, position: Position)`: Get hover information at a position
- `language()`: Get the supported language

### Diagnostics Engine Interface


The `DiagnosticsEngine` trait generates diagnostics for code issues:

```rust
use ricecoder_lsp::diagnostics::{DiagnosticsEngine, DefaultDiagnosticsEngine};
use ricecoder_lsp::types::Language;

// Create a diagnostics engine
let engine = DefaultDiagnosticsEngine::new();

// Generate diagnostics
let diagnostics = engine.generate_diagnostics(code, Language::Rust)?;

// Generate diagnostics for a specific range
let range_diagnostics = engine.generate_diagnostics_for_range(
    code,
    Language::Rust,
    range,
)?;
```

**Key Methods**:

- `generate_diagnostics(code: &str, language: Language)`: Generate all diagnostics
- `generate_diagnostics_for_range(code: &str, language: Language, range: Range)`: Generate diagnostics for a specific range

**Diagnostic Severity Levels**:

- `Error`: Critical issues that prevent compilation
- `Warning`: Potential issues that should be addressed
- `Hint`: Style suggestions and improvements

### Code Actions Engine Interface


The `CodeActionsEngine` trait suggests fixes for identified issues:

```rust
use ricecoder_lsp::code_actions::{CodeActionsEngine, DefaultCodeActionsEngine};

// Create a code actions engine
let engine = DefaultCodeActionsEngine::new();

// Get code actions for a diagnostic
let actions = engine.code_actions_for_diagnostic(diagnostic)?;

// Apply a code action
let fixed_code = engine.apply_code_action(code, action)?;
```

**Key Methods**:

- `code_actions_for_diagnostic(diagnostic: &Diagnostic)`: Get applicable code actions
- `apply_code_action(code: &str, action: &CodeAction)`: Apply a code action to code

### Hover Provider Interface


The `HoverProvider` trait provides hover information:

```rust
use ricecoder_lsp::hover::HoverProvider;
use ricecoder_lsp::types::Position;

// Create a hover provider
let provider = HoverProvider::new();

// Get hover information
let hover = provider.hover_at(code, position)?;
```

**Key Methods**:

- `hover_at(code: &str, position: Position)`: Get hover information at a position

## Usage Examples


### Example 1: Basic Semantic Analysis


```rust
use ricecoder_lsp::semantic::{SemanticAnalyzer, RustAnalyzer};

let code = r#"
fn hello(name: &str) {
    println!("Hello, {}", name);
}
"#;

let analyzer = RustAnalyzer::new();
let semantic_info = analyzer.analyze(code)?;

println!("Symbols: {:?}", semantic_info.symbols);
println!("Imports: {:?}", semantic_info.imports);
```

### Example 2: Generating Diagnostics


```rust
use ricecoder_lsp::diagnostics::DefaultDiagnosticsEngine;
use ricecoder_lsp::types::Language;

let code = r#"
fn unused_function() {
    let unused_var = 42;
}
"#;

let engine = DefaultDiagnosticsEngine::new();
let diagnostics = engine.generate_diagnostics(code, Language::Rust)?;

for diagnostic in diagnostics {
    println!("{}: {}", diagnostic.severity, diagnostic.message);
}
```

### Example 3: Getting Hover Information


```rust
use ricecoder_lsp::hover::HoverProvider;
use ricecoder_lsp::types::Position;

let code = r#"
let x: i32 = 42;
"#;

let provider = HoverProvider::new();
let hover = provider.hover_at(code, Position { line: 0, character: 4 })?;

if let Some(info) = hover {
    println!("Type: {}", info.contents);
}
```

### Example 4: Applying Code Actions


```rust
use ricecoder_lsp::code_actions::DefaultCodeActionsEngine;
use ricecoder_lsp::diagnostics::DefaultDiagnosticsEngine;
use ricecoder_lsp::types::Language;

let code = r#"
use std::collections::HashMap;

fn main() {
    println!("Hello");
}
"#;

let diagnostics_engine = DefaultDiagnosticsEngine::new();
let diagnostics = diagnostics_engine.generate_diagnostics(code, Language::Rust)?;

let actions_engine = DefaultCodeActionsEngine::new();
for diagnostic in diagnostics {
    let actions = actions_engine.code_actions_for_diagnostic(&diagnostic)?;
    for action in actions {
        let fixed = actions_engine.apply_code_action(code, &action)?;
        println!("Fixed code:\n{}", fixed);
    }
}
```

## 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:

```rust
use ricecoder_lsp::semantic::SemanticError;

match analyzer.analyze(code) {
    Ok(info) => println!("Analysis successful"),
    Err(SemanticError::ParseError(msg)) => eprintln!("Parse error: {}", msg),
    Err(SemanticError::UnsupportedLanguage(lang)) => eprintln!("Unsupported: {:?}", lang),
    Err(e) => eprintln!("Error: {}", e),
}
```

## 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:

```bash
cargo test --lib
cargo test --test '*'
cargo test --test '*properties*'
```

## Troubleshooting


### Issue: Analysis is slow


**Solution**: Check cache hit rates and increase cache size if needed.

```bash
RICECODER_LSP_CACHE_SIZE=200 cargo run
```

### Issue: Unsupported language errors


**Solution**: The crate gracefully degrades for unsupported languages. Check logs for details.

```bash
RICECODER_LSP_LOG_LEVEL=debug cargo run
```

### Issue: Diagnostics are missing


**Solution**: Ensure the language is correctly detected. Check language-specific rules.

```rust
let language = Language::from_extension(path);
println!("Detected language: {:?}", language);
```

## Contributing


When adding new features:

1. Add language-specific analyzers in `src/semantic/`
2. Add diagnostic rules in `src/diagnostics/`
3. Add code actions in `src/code_actions/`
4. Add tests in `tests/`
5. 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.