99
1010 internal static class DisposeMethod
1111 {
12- internal static bool TryFindFirst ( ITypeSymbol type , Compilation compilation , Search search , [ NotNullWhen ( true ) ] out IMethodSymbol ? disposeMethod )
12+ internal static IMethodSymbol ? Find ( ITypeSymbol type , Compilation compilation , Search search )
1313 {
14- if ( search == Search . TopLevel )
14+ if ( ! type . IsAssignableTo ( KnownSymbol . IDisposable , compilation ) )
1515 {
16- return TryFind ( type , compilation , search , out disposeMethod ) ||
17- TryFindVirtual ( type , compilation , search , out disposeMethod ) ;
16+ return null ;
1817 }
1918
20- while ( type . IsAssignableTo ( KnownSymbol . IDisposable , compilation ) )
19+ if ( search == Search . TopLevel )
2120 {
22- if ( TryFindFirst ( type , compilation , Search . TopLevel , out disposeMethod ) )
23- {
24- return true ;
25- }
26-
27- type = type . BaseType ;
21+ return type . TryFindFirstMethod ( "Dispose" , x => IsMatch ( x ) , out var topLevel )
22+ ? topLevel
23+ : null ;
2824 }
2925
30- disposeMethod = null ;
31- return false ;
32- }
26+ return type . TryFindFirstMethodRecursive ( "Dispose" , x => IsMatch ( x ) , out var recursive )
27+ ? recursive
28+ : null ;
3329
34- internal static bool IsAccessibleOn ( ITypeSymbol type , Compilation compilation )
35- {
36- if ( type . TypeKind == TypeKind . Interface )
30+ static bool IsMatch ( IMethodSymbol candidate )
3731 {
38- return type . IsAssignableTo ( KnownSymbol . IDisposable , compilation ) ;
32+ return candidate is { DeclaredAccessibility : Accessibility . Public , ReturnsVoid : true , Name : "Dispose" , Parameters : { Length : 0 } } ;
3933 }
40-
41- return TryFind ( type , compilation , Search . Recursive , out var disposeMethod ) &&
42- disposeMethod . ExplicitInterfaceImplementations . IsEmpty ;
4334 }
4435
45- internal static bool TryFind ( ITypeSymbol type , Compilation compilation , Search search , [ NotNullWhen ( true ) ] out IMethodSymbol ? disposeMethod )
36+ internal static bool TryFindVirtual ( ITypeSymbol type , Compilation compilation , Search search , [ NotNullWhen ( true ) ] out IMethodSymbol ? disposeMethod )
4637 {
4738 disposeMethod = null ;
4839 if ( ! type . IsAssignableTo ( KnownSymbol . IDisposable , compilation ) )
@@ -59,30 +50,46 @@ internal static bool TryFind(ITypeSymbol type, Compilation compilation, Search s
5950
6051 static bool IsMatch ( IMethodSymbol candidate )
6152 {
62- return candidate is { DeclaredAccessibility : Accessibility . Public , ReturnsVoid : true , Name : "Dispose" , Parameters : { Length : 0 } } ;
53+ return IsOverrideDispose ( candidate ) ||
54+ IsVirtualDispose ( candidate ) ;
6355 }
6456 }
6557
66- internal static bool TryFindVirtual ( ITypeSymbol type , Compilation compilation , Search search , [ NotNullWhen ( true ) ] out IMethodSymbol ? disposeMethod )
58+ internal static bool TryFindFirst ( ITypeSymbol type , Compilation compilation , Search search , [ NotNullWhen ( true ) ] out IMethodSymbol ? disposeMethod )
6759 {
68- disposeMethod = null ;
69- if ( ! type . IsAssignableTo ( KnownSymbol . IDisposable , compilation ) )
60+ if ( search == Search . TopLevel )
7061 {
71- return false ;
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 ) ;
7269 }
7370
74- if ( search == Search . TopLevel )
71+ while ( type . IsAssignableTo ( KnownSymbol . IDisposable , compilation ) )
7572 {
76- return type . TryFindFirstMethod ( "Dispose" , x => IsMatch ( x ) , out disposeMethod ) ;
73+ if ( TryFindFirst ( type , compilation , Search . TopLevel , out disposeMethod ) )
74+ {
75+ return true ;
76+ }
77+
78+ type = type . BaseType ;
7779 }
7880
79- return type . TryFindFirstMethodRecursive ( "Dispose" , x => IsMatch ( x ) , out disposeMethod ) ;
81+ disposeMethod = null ;
82+ return false ;
83+ }
8084
81- static bool IsMatch ( IMethodSymbol candidate )
85+ internal static bool IsAccessibleOn ( ITypeSymbol type , Compilation compilation )
86+ {
87+ if ( type . TypeKind == TypeKind . Interface )
8288 {
83- return IsOverrideDispose ( candidate ) ||
84- IsVirtualDispose ( candidate ) ;
89+ return type . IsAssignableTo ( KnownSymbol . IDisposable , compilation ) ;
8590 }
91+
92+ return Find ( type , compilation , Search . Recursive ) is { ExplicitInterfaceImplementations : { IsEmpty : true } } ;
8693 }
8794
8895 internal static bool TryFindBaseCall ( MethodDeclarationSyntax virtualDispose , SemanticModel semanticModel , CancellationToken cancellationToken , [ NotNullWhen ( true ) ] out InvocationExpressionSyntax ? baseCall )
0 commit comments