diff --git a/IDisposableAnalyzers.Test/IDISP003DisposeBeforeReassigningTests/ValidCode.cs b/IDisposableAnalyzers.Test/IDISP003DisposeBeforeReassigningTests/ValidCode.cs index 9af3072a..26eba823 100644 --- a/IDisposableAnalyzers.Test/IDISP003DisposeBeforeReassigningTests/ValidCode.cs +++ b/IDisposableAnalyzers.Test/IDISP003DisposeBeforeReassigningTests/ValidCode.cs @@ -26,7 +26,7 @@ public void Dispose() }"; [Test] - public void CreateVariable() + public void LocalDeclaration() { var testCode = @" namespace RoslynSandbox @@ -46,6 +46,83 @@ public void Meh() AnalyzerAssert.Valid(Analyzer, testCode); } + [Test] + public void LocalAssignedInSwitch() + { + var testCode = @" +namespace RoslynSandbox +{ + using System; + using System.IO; + + public static class Foo + { + public static IDisposable Bar(int i) + { + IDisposable result; + switch (i) + { + case 1: + result = File.OpenRead(string.Empty); + break; + case 2: + result = File.OpenRead(string.Empty); + break; + default: + result = null; + break; + } + + return result; + } + } +}"; + + AnalyzerAssert.Valid(Analyzer, testCode); + } + + [Test] + public void LocalAssignedInIfElseSwitch() + { + var testCode = @" +namespace RoslynSandbox +{ + using System; + using System.IO; + + public static class Foo + { + public static IDisposable Bar(int i) + { + IDisposable result; + if (i == 0) + { + result = null; + } + else + { + switch (i) + { + case 1: + result = File.OpenRead(string.Empty); + break; + case 2: + result = File.OpenRead(string.Empty); + break; + default: + result = null; + break; + } + } + + return result; + } + } +}"; + + AnalyzerAssert.Valid(Analyzer, testCode); + } + [Test] public void AssignVariableInitializedWithNull() { diff --git a/IDisposableAnalyzers/Helpers/Disposable.cs b/IDisposableAnalyzers/Helpers/Disposable.cs index 2b15f9d9..d511a39b 100644 --- a/IDisposableAnalyzers/Helpers/Disposable.cs +++ b/IDisposableAnalyzers/Helpers/Disposable.cs @@ -124,7 +124,7 @@ internal static bool IsDisposedAfter(ISymbol local, ExpressionSyntax location, S { foreach (var invocation in walker.Invocations) { - if (location.IsExecutedBefore(invocation) == ExecutedBefore.Yes && + if (location.IsExecutedBefore(invocation).IsEither(ExecutedBefore.Maybe, ExecutedBefore.Yes) && DisposeCall.IsDisposing(invocation, local, semanticModel, cancellationToken)) { return true; diff --git a/IDisposableAnalyzers/Helpers/ExecutedBeforeExt.cs b/IDisposableAnalyzers/Helpers/ExecutedBeforeExt.cs new file mode 100644 index 00000000..144c944b --- /dev/null +++ b/IDisposableAnalyzers/Helpers/ExecutedBeforeExt.cs @@ -0,0 +1,9 @@ +namespace IDisposableAnalyzers +{ + using Gu.Roslyn.AnalyzerExtensions; + + internal static class ExecutedBeforeExt + { + internal static bool IsEither(this ExecutedBefore result, ExecutedBefore first, ExecutedBefore other) => result == first || result == other; + } +} \ No newline at end of file diff --git a/IDisposableAnalyzers/Helpers/ResultExt.cs b/IDisposableAnalyzers/Helpers/ResultExt.cs index d59fe8d5..ecb20aa1 100644 --- a/IDisposableAnalyzers/Helpers/ResultExt.cs +++ b/IDisposableAnalyzers/Helpers/ResultExt.cs @@ -6,4 +6,4 @@ internal static class ResultExt internal static bool IsEither(this Result result, Result first, Result second, Result third) => result == first || result == second || result == third; } -} \ No newline at end of file +} diff --git a/ValidCode/Misc.cs b/ValidCode/Misc.cs index 40c5db82..893cab1f 100644 --- a/ValidCode/Misc.cs +++ b/ValidCode/Misc.cs @@ -72,6 +72,32 @@ private set } } + public static IDisposable AssignLocalInSwitch(int i) + { + IDisposable result; + if (i == 0) + { + result = null; + } + else + { + switch (i) + { + case 1: + result = File.OpenRead(string.Empty); + break; + case 2: + result = File.OpenRead(string.Empty); + break; + default: + result = null; + break; + } + } + + return result; + } + public void Dispose() { this.subscription.Dispose(); diff --git a/paket.lock b/paket.lock index 32454097..a10698bb 100644 --- a/paket.lock +++ b/paket.lock @@ -1,7 +1,7 @@ STORAGE: NONE NUGET remote: http://www.nuget.org/api/v2 - Gu.Roslyn.Extensions (0.4.3.2-dev) + Gu.Roslyn.Extensions (0.4.4-dev) Microsoft.CodeAnalysis.CSharp.Workspaces (>= 2.0) ManagedEsent (1.9.4) - restriction: >= net46 Microsoft.CodeAnalysis.Analyzers (2.6.2) - restriction: >= netstandard1.3