Problem
The LSP layer duplicates state that should live in Workspace:
document_texts: HashMap<PathBuf, String> - tracked separately from workspace files
parse_errors: HashMap<PathBuf, Vec<ParseError>> - tracked separately from workspace files
- Direct
std::fs::read_to_string calls bypassing core abstractions
This violates separation of concerns - LSP should be a thin protocol adapter, not a state manager.
Current Architecture
LspServer (syster-lsp)
├── workspace: Workspace<SyntaxFile>
├── document_texts: HashMap<PathBuf, String> ← DUPLICATED STATE
├── parse_errors: HashMap<PathBuf, Vec<ParseError>> ← DUPLICATED STATE
└── sync_document_texts_from_workspace() ← SYNCING DUPLICATED STATE
Proposed Architecture
LspServer (syster-lsp)
└── workspace: Workspace<SyntaxFile>
└── files: HashMap<PathBuf, WorkspaceFile<T>>
├── source_text: String ← SINGLE SOURCE OF TRUTH
├── errors: Vec<ParseError> ← SINGLE SOURCE OF TRUTH
└── content: T (parsed AST)
Implementation Plan
Benefits
- Single source of truth for document state
- LSP becomes a thin protocol adapter
- Easier testing (mock FileLoader)
- Better separation of concerns
- Reduces bugs from state synchronization issues
Files Affected
syster-base:
crates/syster-base/src/semantic/workspace/file.rs
crates/syster-base/src/semantic/workspace/core.rs
crates/syster-base/src/core/ (new FileLoader trait)
syster-lsp:
crates/syster-lsp/src/server/core.rs
crates/syster-lsp/src/server/document.rs
Problem
The LSP layer duplicates state that should live in
Workspace:document_texts: HashMap<PathBuf, String>- tracked separately from workspace filesparse_errors: HashMap<PathBuf, Vec<ParseError>>- tracked separately from workspace filesstd::fs::read_to_stringcalls bypassing core abstractionsThis violates separation of concerns - LSP should be a thin protocol adapter, not a state manager.
Current Architecture
Proposed Architecture
Implementation Plan
source_text: StringtoWorkspaceFileerrors: Vec<ParseError>toWorkspaceFileFileLoadertrait for abstraction (disk/memory/virtual sources)update_from_text(path, text)method toWorkspacedocument_textsfromLspServer, useworkspace.get_text(path)parse_errorsfromLspServer, useworkspace.get_errors(path)std::fscalls from LSP layerBenefits
Files Affected
syster-base:
crates/syster-base/src/semantic/workspace/file.rscrates/syster-base/src/semantic/workspace/core.rscrates/syster-base/src/core/(new FileLoader trait)syster-lsp:
crates/syster-lsp/src/server/core.rscrates/syster-lsp/src/server/document.rs