Fix DeclaringSyntaxReferences returning empty for VB catch variables#81151
Fix DeclaringSyntaxReferences returning empty for VB catch variables#81151CyrusNajmabadi merged 12 commits intomainfrom
Conversation
Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com>
| Return ImmutableArray.Create(Of SyntaxReference)(_modifiedIdentifierOpt.GetReference()) | ||
| Else | ||
| Return ImmutableArray(Of SyntaxReference).Empty | ||
| ' For catch variables (and potentially other cases), there is no ModifiedIdentifierSyntax. |
There was a problem hiding this comment.
@copilot determine what other cases there may be that hit this. if there are none, assert that this is a catch variable. If tehre are others, enumerate them here and add tests.
There was a problem hiding this comment.
Investigated all usages of VariableLocalSymbol and confirmed that only LocalDeclarationKind.Catch passes Nothing for modifiedIdentifierOpt. Added Debug.Assert(DeclarationKind = LocalDeclarationKind.Catch) in commit 8d731e6.
Analysis:
Catch: PassesNothinginCatchBlockBinder.vb:55Variable,Constant,Static,Using: Always provideModifiedIdentifierSyntaxFor,ForEach: Always provideModifiedIdentifierSyntaxImplicitVariable,FunctionValue: UseSourceLocalSymbol(different type), notVariableLocalSymbol
All tests pass with the assertion.
Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com>
src/Compilers/VisualBasic/Test/Semantic/DeclaringSyntaxNodeTests.vb
Outdated
Show resolved
Hide resolved
| Dim token = tree.GetCompilationUnitRoot().FindToken(position) | ||
| Dim identifierName = token.Parent | ||
|
|
||
| ' Get the symbol for the catch variable |
|
|
||
| ' Check that DeclaringSyntaxReferences returns a non-empty list | ||
| Dim declaringRefs = localSymbol.DeclaringSyntaxReferences | ||
| Assert.Equal(1, declaringRefs.Length) |
There was a problem hiding this comment.
@copilot remove unneeded asserts. Instead, use declaringRefs.Single(). That way it will crash if we don't have exactly one item. Similarly, if we have an IsType check, we don't need a NotNull check.
There was a problem hiding this comment.
Simplified assertions in commit 6e0ec0c:
- Used
.Single()instead of checking length and indexing - Removed redundant
Assert.NotNull(declaredSyntax)sinceAssert.IsTypealready implies not null
Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com>
Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com>
src/Compilers/VisualBasic/Test/Semantic/DeclaringSyntaxNodeTests.vb
Outdated
Show resolved
Hide resolved
|
@dotnet/roslyn-compiler this is ready for review. |
| @@ -928,7 +928,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols | |||
| If _modifiedIdentifierOpt IsNot Nothing Then | |||
There was a problem hiding this comment.
It looks like the first case is unreachable and the entire method implementation could be:
If _modifiedIdentifierOpt IsNot Nothing Then
Return ImmutableArray.Create(Of SyntaxReference)(_modifiedIdentifierOpt.GetReference())
Else
Return MyBase.DeclaringSyntaxReferences
End If
``` #Closed
| Dim code As String = tree.GetText().ToString() | ||
| Dim position As Integer = code.IndexOf("exc", StringComparison.Ordinal) | ||
| Dim token = tree.GetCompilationUnitRoot().FindToken(position) | ||
| Dim identifierName = token.Parent |
|
Done with review pass (commit 7) #Closed |
…r-catch-variable-symbol
| If _modifiedIdentifierOpt IsNot Nothing Then | ||
| Return ImmutableArray.Create(_modifiedIdentifierOpt.GetReference()) | ||
| Else | ||
| Debug.Assert(DeclarationKind = LocalDeclarationKind.Catch, "Only catch variables should have Nothing for _modifiedIdentifierOpt") |
There was a problem hiding this comment.
@copilot please move this assert to the constructor. Specifically, that either _modifiedIdentifierOpt is non-nothing, or DeclarationKind is LocalDeclarationKind.Catch.
|
Done with review pass (commit 10) #Closed |
Co-authored-by: CyrusNajmabadi <4564579+CyrusNajmabadi@users.noreply.github.com>
src/Compilers/VisualBasic/Portable/Symbols/Source/LocalSymbol.vb
Outdated
Show resolved
Hide resolved
AlekseyTs
left a comment
There was a problem hiding this comment.
LGTM (commit 12), assuming CI is passing
Plan: Fix DeclaringSyntaxReferences for Catch Variables ✅
Summary
Fixed an issue where
DeclaringSyntaxReferencesreturned an empty list for catch statement variables in Visual Basic.Solution
Modified the
VariableLocalSymbol.DeclaringSyntaxReferencesproperty inLocalSymbol.vbto fall back to using_identifierToken.Parent.GetReference()when_modifiedIdentifierOptisNothing.Code Review Response
VariableLocalSymbolcreation and confirmed that onlyLocalDeclarationKind.CatchpassesNothingasmodifiedIdentifierOpt. AddedDebug.Assert(DeclarationKind = LocalDeclarationKind.Catch)to enforce this invariant..Single()instead of checking length and indexing, and removed redundantNotNullcheck sinceIsTypealready implies not null.Analysis of all LocalDeclarationKind cases:
Catch: UsesNothingfor modifiedIdentifierOpt ✓Variable,Constant,Static: Always provide ModifiedIdentifierSyntaxUsing: Always provides ModifiedIdentifierSyntaxFor,ForEach: Always provide ModifiedIdentifierSyntaxImplicitVariable,FunctionValue: Use different LocalSymbol types (SourceLocalSymbol), not VariableLocalSymbolTesting Results ✅
Original prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.