1010 internal sealed class FinalizerContextWalker : RecursiveWalker < FinalizerContextWalker >
1111 {
1212 private readonly List < SyntaxNode > usedReferenceTypes = new List < SyntaxNode > ( ) ;
13+ private bool returned ;
1314
1415 private FinalizerContextWalker ( )
1516 {
@@ -19,16 +20,46 @@ private FinalizerContextWalker()
1920
2021 public override void VisitIfStatement ( IfStatementSyntax node )
2122 {
22- if ( node . Condition is IdentifierNameSyntax identifierName &&
23- node . TryFirstAncestor ( out MethodDeclarationSyntax ? methodDeclaration ) &&
24- methodDeclaration . TryFindParameter ( identifierName . Identifier . Text , out _ ) )
23+ if ( IsParameter ( node . Condition as IdentifierNameSyntax ) )
2524 {
2625 this . Visit ( node . Else ) ;
2726 }
27+ else if ( node . Condition is PrefixUnaryExpressionSyntax { Operand : IdentifierNameSyntax identifierName , OperatorToken : { ValueText : "!" } } &&
28+ IsParameter ( identifierName ) )
29+ {
30+ switch ( node . Statement )
31+ {
32+ case ReturnStatementSyntax _:
33+ this . returned = true ;
34+ break ;
35+ case BlockSyntax block :
36+ foreach ( var statement in block . Statements )
37+ {
38+ if ( statement is ReturnStatementSyntax )
39+ {
40+ this . returned = true ;
41+ return ;
42+ }
43+ else
44+ {
45+ this . Visit ( statement ) ;
46+ }
47+ }
48+
49+ break ;
50+ }
51+ }
2852 else
2953 {
3054 base . VisitIfStatement ( node ) ;
3155 }
56+
57+ bool IsParameter ( IdentifierNameSyntax ? id )
58+ {
59+ return id is { } &&
60+ node . TryFirstAncestor ( out MethodDeclarationSyntax ? methodDeclaration ) &&
61+ methodDeclaration . TryFindParameter ( id . Identifier . Text , out _ ) ;
62+ }
3263 }
3364
3465 public override void VisitInvocationExpression ( InvocationExpressionSyntax node )
@@ -49,7 +80,8 @@ candidate.ArgumentList is { } argumentList &&
4980
5081 public override void VisitIdentifierName ( IdentifierNameSyntax node )
5182 {
52- if ( ! IsAssignedNull ( node ) &&
83+ if ( ! this . returned &&
84+ ! IsAssignedNull ( node ) &&
5385 this . SemanticModel . TryGetType ( node , this . CancellationToken , out var type ) &&
5486 type . IsReferenceType &&
5587 type . TypeKind != TypeKind . Error )
@@ -79,6 +111,7 @@ internal static FinalizerContextWalker Borrow(BaseMethodDeclarationSyntax node,
79111 protected override void Clear ( )
80112 {
81113 this . usedReferenceTypes . Clear ( ) ;
114+ this . returned = false ;
82115 base . Clear ( ) ;
83116 }
84117
0 commit comments