Fix #894: hover for locals, ctor params, and members inside init() bodies#899
Merged
Merged
Conversation
…) bodies Hover/semantic lookup walked function and method bodies but never descended into user-defined `init(...)` constructor bodies, so hovering a local variable, a constructor parameter, or a class member referenced inside a constructor returned no result — even though the same reference inside a method body worked. Root cause: the SemanticModel's local-scope machinery was keyed exclusively on FunctionDeclarationSyntax. Constructors are ConstructorDeclarationSyntax whose synthesized FunctionSymbol has a null Declaration, so: - constructor parameters and the implicit `this` were never registered, - constructor body locals were skipped in MapLocalVariables (the bound function's Declaration was null), - Resolve's by-name local fallback (FindContainingFunction) and the implicit-`this` member resolution only considered methods. Fix: generalize the local-declarations scope key from FunctionDeclarationSyntax to SyntaxNode and thread constructors through the same pipeline: - map ctor parameters and the implicit `this` in the struct member loop, - match ctor body locals against the constructor's body syntax in MapLocalVariables via a FunctionSymbol -> ConstructorDeclarationSyntax map, - collect ConstructorDeclarationSyntax into per-file buckets and add FindContainingConstructor so Resolve's by-name fallback covers ctor scopes, - extend ResolveImplicitThisMember to treat ctor bodies as having `this`. Adds regression tests covering hover over a local var, a ctor parameter, and a class member inside an init() body. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.
Fixes #894
Problem
Hovering over a local variable, a constructor parameter, or a class member referenced inside an
init(...)constructor body produced no hover result, while the identical reference inside a normal method body worked correctly.Root cause
The language server's
SemanticModellocal-scope machinery (SemanticLookup.cs) was keyed exclusively onFunctionDeclarationSyntax. G# constructors areConstructorDeclarationSyntax, and their synthesizedFunctionSymbolhas anullDeclaration. As a result the hover/semantic-lookup pipeline never descended into constructor bodies:thiswere never registered in the scope maps.MapLocalVariablesbecause the bound function'sDeclarationwasnull.Resolve's by-name local fallback (FindContainingFunction) and the implicit-thismember resolution (ResolveImplicitThisMember) only considered method declarations, so bare local/member references insideinitnever resolved.Fix
Generalized the local-declarations scope key from
FunctionDeclarationSyntaxtoSyntaxNodeand threaded constructors through the same pipeline that already powers method bodies:thisin the struct member loop (alongside methods).MapLocalVariables, using aFunctionSymbol -> ConstructorDeclarationSyntaxreverse map to recover the declaring syntax.ConstructorDeclarationSyntaxinto per-file buckets and addFindContainingConstructor, soResolve's by-name fallback covers constructor scopes.ResolveImplicitThisMemberto treatinit(...)bodies as having an implicitthisreceiver, so bare member references (e.g.Area = product) resolve to the class member.Hover for locals, constructor parameters, and class members inside
initnow matches method-body behavior exactly.Tests
Added
test/LanguageServer.Tests/Issue894ConstructorHoverTests.cswith regression coverage for:init->(local variable) product int32(parameter) w int32init->Area int32+ its doc commentAll three failed (null hover) before the fix and pass after.
Validation
dotnet build GSharp.sln --configuration Release --no-restore -graph-> succeeded, 0 warnings/errors.dotnet test GSharp.sln --configuration Release --no-build-> 5490 passed, 1 skipped, 0 failed (Core 3340 +1 skipped, Compiler 1360, LanguageServer 340, Interpreter 308, Extensions 104, Sdk 38).