Skip to content

Commit 31373ce

Browse files
authored
Merge pull request #6147 from myblindy/patch-01
Fixes #6075
2 parents c2bc164 + 790bef2 commit 31373ce

File tree

2 files changed

+181
-1
lines changed

2 files changed

+181
-1
lines changed

src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/DisposableFieldsShouldBeDisposedTests.cs

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,186 @@ End Function
651651
}.RunAsync();
652652
}
653653

654+
[Fact, WorkItem(6075, "https://github.com/dotnet/roslyn-analyzers/issues/6075")]
655+
public async Task AsyncDisposableDisposedInExplicitAsyncDisposable_Disposed_NoDiagnosticAsync()
656+
{
657+
await new VerifyCS.Test
658+
{
659+
ReferenceAssemblies = AdditionalMetadataReferences.DefaultWithAsyncInterfaces,
660+
TestCode = @"
661+
using System;
662+
using System.IO;
663+
using System.Net.Http;
664+
using System.Threading.Tasks;
665+
666+
class FileStream2 : IAsyncDisposable
667+
{
668+
public ValueTask DisposeAsync() => default;
669+
}
670+
671+
public sealed class Test : IAsyncDisposable, IDisposable
672+
{
673+
private readonly HttpClient client;
674+
private readonly FileStream2 stream;
675+
676+
public Test()
677+
{
678+
client = new HttpClient();
679+
stream = new FileStream2();
680+
}
681+
682+
public void Dispose()
683+
{
684+
client.Dispose();
685+
}
686+
687+
async ValueTask IAsyncDisposable.DisposeAsync()
688+
{
689+
await stream.DisposeAsync();
690+
}
691+
}
692+
"
693+
}.RunAsync();
694+
695+
await new VerifyVB.Test
696+
{
697+
ReferenceAssemblies = AdditionalMetadataReferences.DefaultWithAsyncInterfaces,
698+
TestCode = @"
699+
Imports System
700+
Imports System.IO
701+
Imports System.Net.Http
702+
Imports System.Threading.Tasks
703+
704+
class FileStream2
705+
implements IAsyncDisposable
706+
public function DisposeAsync() as ValueTask implements IAsyncDisposable.DisposeAsync
707+
return nothing
708+
end function
709+
end class
710+
711+
public class Test
712+
implements IAsyncDisposable, IDisposable
713+
714+
private readonly client as HttpClient
715+
private readonly stream as FileStream2
716+
717+
public sub new()
718+
client = new HttpClient
719+
stream = new FileStream2
720+
end sub
721+
722+
public sub Dispose() implements IDisposable.Dispose
723+
client.Dispose()
724+
end sub
725+
726+
function DisposeAsync() as ValueTask implements IAsyncDisposable.DisposeAsync
727+
return stream.DisposeAsync()
728+
end function
729+
end class
730+
"
731+
}.RunAsync();
732+
733+
await new VerifyVB.Test
734+
{
735+
ReferenceAssemblies = AdditionalMetadataReferences.DefaultWithAsyncInterfaces,
736+
TestCode = @"
737+
Imports System
738+
Imports System.IO
739+
Imports System.Net.Http
740+
Imports System.Threading.Tasks
741+
742+
class FileStream2
743+
implements IAsyncDisposable
744+
public function DisposeAsync() as ValueTask implements IAsyncDisposable.DisposeAsync
745+
return nothing
746+
end function
747+
end class
748+
749+
public class Test
750+
implements IAsyncDisposable, IDisposable
751+
752+
private readonly client as HttpClient
753+
private readonly stream as FileStream2
754+
755+
public sub new()
756+
client = new HttpClient
757+
stream = new FileStream2
758+
end sub
759+
760+
public sub Dispose() implements IDisposable.Dispose
761+
client.Dispose()
762+
end sub
763+
764+
rem arbitrary implementation name
765+
function DisposeOtherAsync() as ValueTask implements IAsyncDisposable.DisposeAsync
766+
return stream.DisposeAsync()
767+
end function
768+
end class
769+
"
770+
}.RunAsync();
771+
}
772+
773+
[Fact, WorkItem(6075, "https://github.com/dotnet/roslyn-analyzers/issues/6075")]
774+
public async Task DisposableDisposedInExplicitDisposable_Disposed_NoDiagnosticAsync()
775+
{
776+
await new VerifyCS.Test
777+
{
778+
ReferenceAssemblies = AdditionalMetadataReferences.DefaultWithAsyncInterfaces,
779+
TestCode = @"
780+
using System;
781+
using System.IO;
782+
using System.Net.Http;
783+
using System.Threading.Tasks;
784+
785+
public sealed class Test : IDisposable
786+
{
787+
private readonly HttpClient client;
788+
private readonly FileStream stream;
789+
790+
public Test()
791+
{
792+
client = new HttpClient();
793+
stream = new FileStream(""C://some-path"", FileMode.CreateNew);
794+
}
795+
796+
void IDisposable.Dispose()
797+
{
798+
client.Dispose();
799+
stream.Dispose();
800+
}
801+
}
802+
"
803+
}.RunAsync();
804+
805+
await new VerifyVB.Test
806+
{
807+
ReferenceAssemblies = AdditionalMetadataReferences.DefaultWithAsyncInterfaces,
808+
TestCode = @"
809+
Imports System
810+
Imports System.IO
811+
Imports System.Net.Http
812+
Imports System.Threading.Tasks
813+
814+
public class Test
815+
implements IDisposable
816+
817+
private readonly client as HttpClient
818+
private readonly stream as FileStream
819+
820+
public sub new()
821+
client = new HttpClient
822+
stream = new FileStream(""C://some-path"", FileMode.CreateNew)
823+
end sub
824+
825+
public sub Dispose() implements IDisposable.Dispose
826+
client.Dispose()
827+
stream.Dispose()
828+
end sub
829+
end class
830+
"
831+
}.RunAsync();
832+
}
833+
654834
[Fact]
655835
public async Task DisposableAllocation_AssignedThroughLocal_Disposed_NoDiagnosticAsync()
656836
{

src/Utilities/Compiler/Extensions/IMethodSymbolExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ public static DisposeMethodKind GetDisposeMethodKind(
337337
{
338338
return DisposeMethodKind.DisposeBool;
339339
}
340-
else if (method.HasDisposeAsyncMethodSignature(task, valueTask))
340+
else if (method.IsAsyncDisposeImplementation(iAsyncDisposable, valueTask) || method.HasDisposeAsyncMethodSignature(task, valueTask))
341341
{
342342
return DisposeMethodKind.DisposeAsync;
343343
}

0 commit comments

Comments
 (0)