Merged
Conversation
Semantic API additions for upcoming LSP features: - Ingot::all_funcs() collects all functions across modules - Func::containing_impl() finds parent impl block - ImplTrait::implementing_adt() resolves implementing struct/enum - CallSiteView + Body::call_sites() for iterating call expressions
…tion range Four new LSP features: - Call hierarchy: incoming/outgoing call navigation - Type hierarchy: supertype (traits) and subtype (implementors) navigation - Code lens: reference and implementation counts on symbols - Selection range: AST-aware expand/shrink selection
Generates LSIF 0.4.0 index for code navigation (GitHub, Sourcegraph). Emits definitions, references, hover content, and monikers for all symbols in an ingot. Usage: fe lsif <path> [-o output]
Extract find_incoming_calls/find_outgoing_calls helpers from handlers for testability. Tests cover prepare, incoming calls, outgoing calls, and empty cases.
Extract find_supertypes/find_subtypes helpers from handlers. Tests cover prepare on struct/trait, supertypes from trait impls, subtypes from trait implementors, and empty cases.
Extract collect_lens_data helper. Tests cover reference counting on structs/functions, trait implementation counting, and zero-reference cases.
Extract build_selection_ranges_at helper. Tests verify nested ranges on function names, inside bodies, nested items (method inside impl), and cursor outside items.
Pre-emit document vertices for all modules, track via HashMap to avoid emitting duplicate documents when multiple modules share a file. Collect range IDs per document for proper contains edges.
Validate LSIF output structure: required fields, edge references, vertex ordering, metadata, document deduplication, hover content, range positions, monikers, and contains edges.
Eliminates dead code warnings for collect_lens_data and build_selection_ranges_at, which are only used by tests.
Folding ranges uses scope graph traversal to fold multi-line functions, structs, enums, traits, impls, and impl trait blocks. Go-to-declaration navigates to the concrete declaration site, complementing goto-definition which redirects impl trait methods to their trait method declarations.
The LSP spec expects SymbolInformation.name to be just the identifier, with the kind field indicating the symbol type. Removing prefixes like "fn " and "struct " enables proper syntax highlighting in editors that use label_for_symbol to wrap names in highlighted code snippets.
Collapse nested if statements using let-chains, use HashMap entry API instead of contains_key+insert, iterate map values directly.
Extract the temp-directory + bidirectional URI mapping from BuiltinFiles into a generic VirtualFiles abstraction. Add codegen output generation (MIR, Yul, Sonatina IR) exposed via workspace/executeCommand, with code lenses per file to trigger each view. The generated IR is materialized into the VFS temp directory and opened in the editor via showDocument.
Adds fn/struct/enum/trait/type/const/mod/contract prefixes back to symbol names so Zed's symbol browser can syntax-highlight them.
When a fe.toml exists at the repo root, containing_ingot() would claim all .fe files as part of that ingot, even files like test_files/goto.fe that aren't under src/. This led to a panic in module_tree_impl when the ingot had no discoverable source files. Fix: check that the file is actually under the ingot's src/ directory or at the ingot root before claiming it. Files outside the source tree now fall through to standalone ingot detection. Also add a safety net in module_tree_impl: return an empty module tree instead of panicking when no source files are found.
The code lenses were using custom fe.showReferences and fe.showImplementations commands that were never registered, causing "command not found" when clicked. Switch to the standard editor.action.showReferences command with actual reference locations as arguments, which both VS Code and Zed handle natively.
- Remove TracingLayer to fix feedback loop that crashed Zed (every window/logMessage notification was re-logged, flooding the client) - Lower default log level from INFO to WARN for window/logMessage - Use fe.showReferences instead of editor.action.showReferences so the VS Code extension can bridge JSON args to native VS Code types - Show friendly warning instead of internal error when codegen fails due to type errors in the source file - Add showDocument -> applyEdit fallback for codegen viewer in editors that don't support window/showDocument (Zed) - Fix readonly file overwrite in VirtualFiles for codegen regeneration
95cb3ef to
b59b199
Compare
Fix three issues causing the language server to get stuck or crash: - Use content_changes.last() instead of [0] in didChange handler to correctly pick up the final file state under FULL sync mode - Clear stale diagnostics for URIs not covered by the computed diagnostics map, preventing phantom errors after fixes - Wrap mir_diagnostics_for_ingot in catch_unwind to prevent panics in MIR analysis (missing spans, invalid IDs) from killing the Backend actor and causing SendError on all subsequent requests Add regression tests covering malformed mid-edit states: truncated source, empty files, garbage content, partial generics, incomplete function bodies, and the reported "mself" intermediate edit scenario.
Fix three parser panics that caused the language server to crash during editing, leaving it in a permanently broken state (all subsequent LSP requests fail with SendError): 1. parser/struct_.rs: ErrorScope leak when parsing fn inside struct def. Manual enter(ErrorScope)/parse(FuncScope)?/leave() pattern skipped leave() on error propagation via ?, corrupting the scope stack and producing a non-Root green tree. Fix: capture result before ?. 2. parser/param.rs: unreachable!() in GenericParamListScope when recovery lands on a list separator (e.g. `struct S<,>`). 3. parser/syntax_kind.rs: todo!() and unimplemented!() in describe() for Error and InvalidToken syntax kinds. Add catch_unwind safety net around diagnostics_for_ingot in the LSP handler so future panics in analysis passes degrade gracefully instead of killing the backend actor. Add mock LSP client test harness (mock_client_tests.rs) with 7 integration tests covering formatting during malformed states, keystroke sequences, and concurrent diagnostics. Add fuzz test with ~70 malformed inputs covering Sean's reported crash scenarios.
b59b199 to
067b7d1
Compare
067b7d1 to
4b9d428
Compare
- Bounds-check line index in to_offset_from_position to prevent panics on stale document positions from the client - Clamp byte offset to text length to avoid out-of-range TextSize - Replace O(n^2) chars().nth().unwrap() with as_bytes() in item_info line-start scan, fixing both a performance issue and panic on non-ASCII - Document type_hierarchy_provider gap in lsp-types 0.95.1
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 993752767f
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
- Replace unreachable!() with warning on unknown FileChangeType - Replace unwrap() on channel sends in lsp_streams with error propagation so a dropped receiver returns a proper LSP error instead of crashing - Convert expect() to fallible ? in to_lsp_location_from_span so files without URLs don't crash the diagnostics path - Unify calculate_line_offsets with the LSIF/SCIP byte-scanning implementation, fixing edge cases with trailing newlines - Adjust folding range end line when spans include trailing newlines, so folds end on the closing brace line instead of the line after
…y gap - Check the success field in the showDocument response, not just whether the RPC succeeded. Clients that return success:false now correctly fall through to the workspace/applyEdit path. - Document that incoming call hierarchy doesn't yet scan contract init/recv bodies.
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
LSP features and crash fixes
New features
fe lsif,fe scip)Crash fixes
The reported crash (Sean's
SendErrorduring formatting mid-edit) came from three parser panic paths:struct_.rs, error recovery scope entered but never left due to early?return, corrupting the scope stack and causingast::Root::cast().unwrap()to fail in HIR lowering.unreachable!()in generic params, error recovery landing on unexpected tokens. Changed to graceful return.todo!()/unimplemented!()inSyntaxKind::describe(), replaced with string returns.Added
catch_unwindaround diagnostics so future parser issues degrade to missing diagnostics instead of crashing.Other fixes
content_changes[0]instead of.last()in full-sync modeshowDocumentfallback checkssuccessfield, not just RPC statusTests