Skip to content

Commit 70230d2

Browse files
committed
Handle recursive builder
1 parent 5b98dee commit 70230d2

4 files changed

Lines changed: 48 additions & 4 deletions

File tree

IDisposableAnalyzers.Test/Helpers/DisposableTests.Ignores.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,6 +1089,43 @@ public void Dispose()
10891089
var value = syntaxTree.FindExpression(expressionText);
10901090
Assert.AreEqual(false, Disposable.Ignores(value, semanticModel, CancellationToken.None));
10911091
}
1092+
1093+
[Test]
1094+
public static void Builder()
1095+
{
1096+
var syntaxTree = CSharpSyntaxTree.ParseText("""
1097+
namespace N;
1098+
1099+
using System;
1100+
1101+
public record struct S : IDisposable
1102+
{
1103+
public S Append(int value)
1104+
{
1105+
if (value > 3)
1106+
{
1107+
return this;
1108+
}
1109+
1110+
throw new Exception();
1111+
}
1112+
1113+
internal S Append(bool value) => this.Append(1);
1114+
1115+
public void Dispose() { }
1116+
1117+
public void M()
1118+
{
1119+
using var s = new S().Append(true);
1120+
}
1121+
}
1122+
""");
1123+
1124+
var compilation = CSharpCompilation.Create("test", new[] { syntaxTree }, Settings.Default.MetadataReferences);
1125+
var semanticModel = compilation.GetSemanticModel(syntaxTree);
1126+
var value = syntaxTree.FindExpression("new S()");
1127+
Assert.AreEqual(false, Disposable.Ignores(value, semanticModel, CancellationToken.None));
1128+
}
10921129
}
10931130
}
10941131
}

IDisposableAnalyzers.Test/IDISP004DoNotIgnoreCreatedTests/Valid.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -966,6 +966,8 @@ public S Append(int value)
966966
throw new Exception();
967967
}
968968
969+
internal S Append(bool value) => this.Append(1);
970+
969971
public void Dispose() { }
970972
}
971973
""";
@@ -976,7 +978,7 @@ sealed class C
976978
{
977979
void M()
978980
{
979-
using var s = new S().Append(1);
981+
using var s = new S().Append(true);
980982
}
981983
}
982984
""";

IDisposableAnalyzers/Helpers/Disposable.Identity.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,14 @@ when target.Declaration is MethodDeclarationSyntax methodDeclaration &&
113113
{
114114
foreach (var returnValue in walker.ReturnValues)
115115
{
116-
if (returnValue is ThisExpressionSyntax)
116+
switch (returnValue)
117117
{
118-
return true;
118+
case ThisExpressionSyntax:
119+
return true;
120+
case InvocationExpressionSyntax invocation
121+
when recursion.Target(invocation) is { Symbol: { IsStatic: false } } next &&
122+
next.Symbol.ContainingType.IsAssignableTo(target.Symbol.ContainingType, recursion.SemanticModel.Compilation):
123+
return IsIdentity(next, recursion);
119124
}
120125
}
121126
}

ValidCode/StructBuilder/Request.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
using System.Threading;
99

1010
[DebuggerDisplay("{ToString(),nq}")]
11-
public record struct Request : IDisposable
11+
public struct Request : IDisposable
1212
{
1313
private static int id;
1414

0 commit comments

Comments
 (0)