Skip to content

Commit 9480747

Browse files
committed
Return nullable.
1 parent 90e4bcb commit 9480747

7 files changed

Lines changed: 27 additions & 32 deletions

File tree

IDisposableAnalyzers.Test/Helpers/DisposeMethodTests.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ private void ThrowIfDisposed()
8888

8989
[TestCase(Search.TopLevel)]
9090
[TestCase(Search.Recursive)]
91-
public static void TryFindVirtualDispose(Search search)
91+
public static void FindVirtual(Search search)
9292
{
9393
var code = @"
9494
namespace N
@@ -130,13 +130,12 @@ protected virtual void ThrowIfDisposed()
130130
var compilation = CSharpCompilation.Create("test", new[] { syntaxTree }, MetadataReferences.FromAttributes());
131131
var semanticModel = compilation.GetSemanticModel(syntaxTree);
132132
var method = semanticModel.GetDeclaredSymbol(syntaxTree.FindClassDeclaration("C"));
133-
Assert.AreEqual(true, DisposeMethod.TryFindVirtual(method, compilation, search, out var match));
134-
Assert.AreEqual("N.C.Dispose(bool)", match.ToString());
133+
Assert.AreEqual("N.C.Dispose(bool)", DisposeMethod.FindVirtual(method, compilation, search).ToString());
135134
}
136135

137136
[TestCase(Search.TopLevel)]
138137
[TestCase(Search.Recursive)]
139-
public static void TryFindFirst(Search search)
138+
public static void FindFirst(Search search)
140139
{
141140
var code = @"
142141
namespace N
@@ -178,8 +177,7 @@ protected virtual void ThrowIfDisposed()
178177
var compilation = CSharpCompilation.Create("test", new[] { syntaxTree }, MetadataReferences.FromAttributes());
179178
var semanticModel = compilation.GetSemanticModel(syntaxTree);
180179
var method = semanticModel.GetDeclaredSymbol(syntaxTree.FindClassDeclaration("C"));
181-
Assert.AreEqual(true, DisposeMethod.TryFindFirst(method, compilation, search, out var match));
182-
Assert.AreEqual("N.C.Dispose()", match.ToString());
180+
Assert.AreEqual("N.C.Dispose()", DisposeMethod.FindFirst(method, compilation, search).ToString());
183181
}
184182
}
185183
}

IDisposableAnalyzers/Analyzers/ClassDeclarationAnalyzer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ private static void Handle(SyntaxNodeAnalysisContext context)
2626
context.ContainingSymbol is INamedTypeSymbol { IsSealed: false } type &&
2727
type.IsAssignableTo(KnownSymbol.IDisposable, context.SemanticModel.Compilation) &&
2828
DisposeMethod.Find(type, context.Compilation, Search.TopLevel) is { IsVirtual: false, IsOverride: false } disposeMethod &&
29-
!DisposeMethod.TryFindVirtual(type, context.Compilation, Search.TopLevel, out _))
29+
DisposeMethod.FindVirtual(type, context.Compilation, Search.TopLevel) is null)
3030
{
3131
context.ReportDiagnostic(
3232
Diagnostic.Create(

IDisposableAnalyzers/Analyzers/FieldAndPropertyDeclarationAnalyzer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ private static void HandleFieldOrProperty(SyntaxNodeAnalysisContext context, Fie
6464
context.ReportDiagnostic(Diagnostic.Create(Descriptors.IDISP002DisposeMember, context.Node.GetLocation()));
6565

6666
if (!TestFixture.IsAssignedInInitialize(member, context.SemanticModel, context.CancellationToken, out _, out _) &&
67-
!DisposeMethod.TryFindFirst(member.FieldOrProperty.ContainingType, context.Compilation, Search.TopLevel, out _))
67+
DisposeMethod.FindFirst(member.FieldOrProperty.ContainingType, context.Compilation, Search.TopLevel) is null)
6868
{
6969
context.ReportDiagnostic(Diagnostic.Create(Descriptors.IDISP006ImplementIDisposable, member.Declaration.GetLocation()));
7070
}

IDisposableAnalyzers/CodeFixes/DisposeMemberFix.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,13 @@ protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContex
3333
semanticModel.TryGetSymbol(member, context.CancellationToken, out ISymbol? symbol) &&
3434
FieldOrProperty.TryCreate(symbol, out var disposable))
3535
{
36-
if (DisposeMethod.TryFindVirtual(symbol.ContainingType, semanticModel.Compilation, Search.TopLevel, out var disposeSymbol) &&
37-
disposeSymbol.TrySingleDeclaration(context.CancellationToken, out MethodDeclarationSyntax? disposeDeclaration))
36+
if (DisposeMethod.FindVirtual(symbol.ContainingType, semanticModel.Compilation, Search.TopLevel) is { } virtualDispose &&
37+
virtualDispose.TrySingleDeclaration(context.CancellationToken, out MethodDeclarationSyntax? disposeDeclaration))
3838
{
3939
if (disposeDeclaration is { ParameterList: { Parameters: { Count: 1 } parameters }, Body: { } block })
4040
{
4141
context.RegisterCodeFix(
42-
$"{symbol.Name}.Dispose() in {disposeSymbol}",
42+
$"{symbol.Name}.Dispose() in {virtualDispose}",
4343
(editor, token) => Dispose(editor, token),
4444
"Dispose member.",
4545
diagnostic);

IDisposableAnalyzers/Helpers/Disposable.Ignores.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ bool IsIgnored(IdentifierNameSyntax candidate)
111111
when right == candidate &&
112112
recursion.SemanticModel.TryGetSymbol(left, recursion.CancellationToken, out var assignedSymbol) &&
113113
FieldOrProperty.TryCreate(assignedSymbol, out var assignedMember):
114-
if (DisposeMethod.TryFindFirst(assignedMember.ContainingType, recursion.SemanticModel.Compilation, Search.TopLevel, out var disposeMethod) &&
114+
if (DisposeMethod.FindFirst(assignedMember.ContainingType, recursion.SemanticModel.Compilation, Search.TopLevel) is { } disposeMethod &&
115115
DisposableMember.IsDisposed(assignedMember, disposeMethod, recursion.SemanticModel, recursion.CancellationToken))
116116
{
117117
return Ignores(parentExpression, recursion);

IDisposableAnalyzers/Helpers/DisposeMethod.cs

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,23 @@ static bool IsMatch(IMethodSymbol candidate)
3333
}
3434
}
3535

36-
internal static bool TryFindVirtual(ITypeSymbol type, Compilation compilation, Search search, [NotNullWhen(true)] out IMethodSymbol? disposeMethod)
36+
internal static IMethodSymbol? FindVirtual(ITypeSymbol type, Compilation compilation, Search search)
3737
{
38-
disposeMethod = null;
3938
if (!type.IsAssignableTo(KnownSymbol.IDisposable, compilation))
4039
{
41-
return false;
40+
return null;
4241
}
4342

4443
if (search == Search.TopLevel)
4544
{
46-
return type.TryFindFirstMethod("Dispose", x => IsMatch(x), out disposeMethod);
45+
return type.TryFindFirstMethod("Dispose", x => IsMatch(x), out var topLevel)
46+
? topLevel
47+
: null;
4748
}
4849

49-
return type.TryFindFirstMethodRecursive("Dispose", x => IsMatch(x), out disposeMethod);
50+
return type.TryFindFirstMethodRecursive("Dispose", x => IsMatch(x), out var recursive)
51+
? recursive
52+
: null;
5053

5154
static bool IsMatch(IMethodSymbol candidate)
5255
{
@@ -55,31 +58,25 @@ static bool IsMatch(IMethodSymbol candidate)
5558
}
5659
}
5760

58-
internal static bool TryFindFirst(ITypeSymbol type, Compilation compilation, Search search, [NotNullWhen(true)] out IMethodSymbol? disposeMethod)
61+
internal static IMethodSymbol? FindFirst(ITypeSymbol type, Compilation compilation, Search search)
5962
{
6063
if (search == Search.TopLevel)
6164
{
62-
if (Find(type, compilation, search) is { } match)
63-
{
64-
disposeMethod = match;
65-
return true;
66-
}
67-
68-
return TryFindVirtual(type, compilation, search, out disposeMethod);
65+
return Find(type, compilation, Search.TopLevel) ??
66+
FindVirtual(type, compilation, Search.TopLevel);
6967
}
7068

7169
while (type.IsAssignableTo(KnownSymbol.IDisposable, compilation))
7270
{
73-
if (TryFindFirst(type, compilation, Search.TopLevel, out disposeMethod))
71+
if (FindFirst(type, compilation, Search.TopLevel) is { } disposeMethod)
7472
{
75-
return true;
73+
return disposeMethod;
7674
}
7775

7876
type = type.BaseType;
7977
}
8078

81-
disposeMethod = null;
82-
return false;
79+
return null;
8380
}
8481

8582
internal static bool IsAccessibleOn(ITypeSymbol type, Compilation compilation)

IDisposableAnalyzers/Helpers/Walkers/DisposeWalker.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,15 @@ public override void VisitIdentifierName(IdentifierNameSyntax node)
4646
internal static DisposeWalker Borrow(INamedTypeSymbol type, SemanticModel semanticModel, CancellationToken cancellationToken)
4747
{
4848
if (type.IsAssignableTo(KnownSymbol.IDisposable, semanticModel.Compilation) &&
49-
DisposeMethod.TryFindFirst(type, semanticModel.Compilation, Search.Recursive, out var disposeMethod) &&
49+
DisposeMethod.FindFirst(type, semanticModel.Compilation, Search.Recursive) is { } disposeMethod &&
5050
disposeMethod.TrySingleDeclaration(cancellationToken, out MethodDeclarationSyntax? declaration))
5151
{
5252
return BorrowAndVisit(declaration, SearchScope.Instance, type, semanticModel, () => new DisposeWalker(), cancellationToken);
5353
}
5454

5555
if (type.IsAssignableTo(KnownSymbol.IAsyncDisposable, semanticModel.Compilation) &&
56-
type.TryFindFirstMethod(x => x is { Parameters: { Length: 0 } } && x == KnownSymbol.IAsyncDisposable.DisposeAsync, out disposeMethod) &&
57-
disposeMethod.TrySingleDeclaration(cancellationToken, out declaration))
56+
type.TryFindFirstMethod(x => x is { Parameters: { Length: 0 } } && x == KnownSymbol.IAsyncDisposable.DisposeAsync, out var disposeAsync) &&
57+
disposeAsync.TrySingleDeclaration(cancellationToken, out declaration))
5858
{
5959
return BorrowAndVisit(declaration, SearchScope.Instance, type, semanticModel, () => new DisposeWalker(), cancellationToken);
6060
}

0 commit comments

Comments
 (0)