Skip to content

Commit 958acf6

Browse files
MafiiJohanLarsson
authored andcommitted
Add implementation for DisposeWith on variable declarations
1 parent 7d07dbd commit 958acf6

File tree

1 file changed

+52
-0
lines changed

1 file changed

+52
-0
lines changed

IDisposableAnalyzers/Helpers/Disposable.ShouldDispose.cs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ internal static bool ShouldDispose(LocalOrParameter localOrParameter, SemanticMo
2222
return false;
2323
}
2424

25+
if (Scope() is BlockSyntax localBlock && IsVariableDeclarationWithDisposeAsExtensionCall(localBlock))
26+
{
27+
return false;
28+
}
29+
2530
using var recursion = Recursion.Borrow(localOrParameter.Symbol.ContainingType, semanticModel, cancellationToken);
2631
using var walker = UsagesWalker.Borrow(localOrParameter, semanticModel, cancellationToken);
2732
foreach (var usage in walker.Usages)
@@ -112,4 +117,51 @@ static bool ShouldNotDispose(IdentifierNameSyntax usage, Recursion recursion)
112117
return false;
113118
}
114119
}
120+
121+
private static bool IsVariableDeclarationWithDisposeAsExtensionCall(BlockSyntax localBlock)
122+
{
123+
if (localBlock is not { Statements: { Count: 1 } statements })
124+
{
125+
return false;
126+
}
127+
128+
if (statements[0] is not LocalDeclarationStatementSyntax { Declaration: { } variableDeclaration })
129+
{
130+
return false;
131+
}
132+
133+
if (variableDeclaration.Variables is not { Count: 1 } vars)
134+
{
135+
return false;
136+
}
137+
138+
if (vars[0].Initializer is not { } rhs)
139+
{
140+
return false;
141+
}
142+
143+
// For simplicity reasons, we do not validate the variable type, or what is to the left of the call.
144+
// Instead, we simply check if the last invocation of the rhs is `.DisposeWith(<one argument>);`
145+
if (rhs.Value is not InvocationExpressionSyntax lastInvocationInChain)
146+
{
147+
return false;
148+
}
149+
150+
if (lastInvocationInChain.Expression is not MemberAccessExpressionSyntax memberAccess)
151+
{
152+
return false;
153+
}
154+
155+
if (memberAccess.Name.Identifier.Value is not "DisposeWith")
156+
{
157+
return false;
158+
}
159+
160+
if (lastInvocationInChain.ArgumentList.Arguments is not { Count: 1 } arguments)
161+
{
162+
return false;
163+
}
164+
165+
return true;
166+
}
115167
}

0 commit comments

Comments
 (0)