Improve LSP Hover and Completion for Reduce Action Bindings#84
Conversation
There was a problem hiding this comment.
Code Review
This pull request enhances the Language Server Protocol (LSP) implementation for RustyLR by providing rich hover information and completion suggestions inside reduce actions. It introduces support for resolving semantic value bindings, positional variables, location references, and GLR control variables (such as data, lookahead, shift, and Err), including resolving types after substitution (e.g., resolving $moduleprefix references). Feedback on the changes includes addressing a stack corruption issue in resolve_provider_stream due to an early return bypassing stack.pop(), and decoupling the collection of default binding types from token references in variables_for_offset to ensure types are always populated when a grammar is available.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| if let (Some(grammar), Some(reference)) = | ||
| (&grammar, token_references.get(variables.value_count - 1)) | ||
| { | ||
| collect_default_binding_types( | ||
| args, | ||
| grammar, | ||
| pattern, | ||
| &mut variables.value_types, | ||
| ); | ||
| collect_default_binding_references( | ||
| pattern, | ||
| reference, | ||
| &mut variables.value_references, | ||
| ); | ||
| } |
There was a problem hiding this comment.
In variables_for_offset, the collection of default binding types is incorrectly coupled with the presence of reference (token references). If reference is None (e.g., if reference resolution fails or is not applicable), collect_default_binding_types is never called, meaning default bindings will not have their types populated and won't be suggested in completion. Decouple the two operations so that default binding types are always collected as long as grammar is available.
| if let (Some(grammar), Some(reference)) = | |
| (&grammar, token_references.get(variables.value_count - 1)) | |
| { | |
| collect_default_binding_types( | |
| args, | |
| grammar, | |
| pattern, | |
| &mut variables.value_types, | |
| ); | |
| collect_default_binding_references( | |
| pattern, | |
| reference, | |
| &mut variables.value_references, | |
| ); | |
| } | |
| if let Some(grammar) = &grammar { | |
| collect_default_binding_types( | |
| args, | |
| grammar, | |
| pattern, | |
| &mut variables.value_types, | |
| ); | |
| } | |
| if let Some(reference) = token_references.get(variables.value_count - 1) { | |
| collect_default_binding_references( | |
| pattern, | |
| reference, | |
| &mut variables.value_references, | |
| ); | |
| } |
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
data,lookahead,shift,Err,@0, and@$.%moduleprefix,%userdata,%location,%error/%errortype, and%tokentype.$1/$2positional values, and@1/@2location references using a caret marker under the referenced RHS token.