Skip to content

Commit c3647bf

Browse files
5
1 parent ae4d206 commit c3647bf

7 files changed

Lines changed: 489 additions & 170 deletions

File tree

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
namespace Pure.DI.Core.Code;
2+
3+
sealed class DisposalStatementsBuilder : IDisposalStatementsBuilder
4+
{
5+
public void AddDisposeLoop(
6+
Lines code,
7+
bool hasDisposable,
8+
bool hasAsyncDisposable,
9+
bool isAsync,
10+
string onDisposeExceptionCall,
11+
string onDisposeAsyncExceptionCall)
12+
{
13+
code.AppendLine("while (disposeIndex-- > 0)");
14+
using (code.CreateBlock())
15+
{
16+
code.AppendLine("switch (disposables[disposeIndex])");
17+
using (code.CreateBlock())
18+
{
19+
if (isAsync)
20+
{
21+
if (hasAsyncDisposable)
22+
{
23+
AddDisposeAsyncPart(code, true, onDisposeAsyncExceptionCall);
24+
}
25+
26+
if (hasDisposable)
27+
{
28+
if (hasAsyncDisposable)
29+
{
30+
code.AppendLine();
31+
}
32+
33+
AddDisposePart(code, onDisposeExceptionCall);
34+
}
35+
}
36+
else
37+
{
38+
if (hasDisposable)
39+
{
40+
AddDisposePart(code, onDisposeExceptionCall);
41+
}
42+
43+
if (hasAsyncDisposable)
44+
{
45+
if (hasDisposable)
46+
{
47+
code.AppendLine();
48+
}
49+
50+
AddDisposeAsyncPart(code, false, onDisposeAsyncExceptionCall);
51+
}
52+
}
53+
}
54+
}
55+
}
56+
57+
private static void AddDisposeAsyncPart(Lines code, bool makeAsyncCall, string onDisposeAsyncExceptionCall)
58+
{
59+
code.AppendLine($"case {Names.IAsyncDisposableTypeName} asyncDisposableInstance:");
60+
using (code.Indent())
61+
{
62+
code.AppendLine("try");
63+
using (code.CreateBlock())
64+
{
65+
if (makeAsyncCall)
66+
{
67+
code.AppendLine("await asyncDisposableInstance.DisposeAsync();");
68+
}
69+
else
70+
{
71+
code.AppendLine("var valueTask = asyncDisposableInstance.DisposeAsync();");
72+
code.AppendLine("if (!valueTask.IsCompleted)");
73+
using (code.CreateBlock())
74+
{
75+
code.AppendLine("valueTask.AsTask().Wait();");
76+
}
77+
}
78+
}
79+
80+
code.AppendLine($"catch ({Names.ExceptionTypeName} exception)");
81+
using (code.CreateBlock())
82+
{
83+
code.AppendLine($"{onDisposeAsyncExceptionCall};");
84+
}
85+
86+
code.AppendLine("break;");
87+
}
88+
}
89+
90+
private static void AddDisposePart(Lines code, string onDisposeExceptionCall)
91+
{
92+
code.AppendLine($"case {Names.IDisposableTypeName} disposableInstance:");
93+
using (code.Indent())
94+
{
95+
code.AppendLine("try");
96+
using (code.CreateBlock())
97+
{
98+
code.AppendLine("disposableInstance.Dispose();");
99+
}
100+
101+
code.AppendLine($"catch ({Names.ExceptionTypeName} exception)");
102+
using (code.CreateBlock())
103+
{
104+
code.AppendLine($"{onDisposeExceptionCall};");
105+
}
106+
107+
code.AppendLine("break;");
108+
}
109+
}
110+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace Pure.DI.Core.Code;
2+
3+
interface IDisposalStatementsBuilder
4+
{
5+
void AddDisposeLoop(
6+
Lines code,
7+
bool hasDisposable,
8+
bool hasAsyncDisposable,
9+
bool isAsync,
10+
string onDisposeExceptionCall,
11+
string onDisposeAsyncExceptionCall);
12+
}

src/Pure.DI.Core/Core/Code/Parts/DisposeMethodBuilder.cs

Lines changed: 27 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ namespace Pure.DI.Core.Code.Parts;
66

77
sealed class DisposeMethodBuilder(
88
ITypeResolver typeResolver,
9-
ILocks locks)
9+
ILocks locks,
10+
IDisposalStatementsBuilder disposalStatementsBuilder)
1011
: IClassPartBuilder
1112
{
1213
public ClassPart Part => ClassPart.DisposeMethod;
@@ -42,32 +43,17 @@ public CompositionCode Build(CompositionCode composition)
4243
code.AppendLine($"{composition.Source.Source.Hints.DisposeMethodModifiers} void Dispose()");
4344
using (code.CreateBlock())
4445
{
45-
AddSyncPart(composition, code, false, rootDisposablesCount, hasStateObjectScope, hasScopedLifetimes, singletonFieldsToReset);
46+
AddSyncPart(composition, code, false, rootDisposablesCount, hasStateObjectScope, hasScopedLifetimes, hasAsyncDisposable, singletonFieldsToReset);
4647
if (rootDisposablesCount > 0)
4748
{
4849
code.AppendLine();
49-
code.AppendLine("while (disposeIndex-- > 0)");
50-
using (code.CreateBlock())
51-
{
52-
code.AppendLine("switch (disposables[disposeIndex])");
53-
using (code.CreateBlock())
54-
{
55-
if (hasDisposable)
56-
{
57-
AddDisposePart(code);
58-
}
59-
60-
if (hasAsyncDisposable)
61-
{
62-
if (hasDisposable)
63-
{
64-
code.AppendLine();
65-
}
66-
67-
AddDisposeAsyncPart(code, false);
68-
}
69-
}
70-
}
50+
disposalStatementsBuilder.AddDisposeLoop(
51+
code,
52+
hasDisposable,
53+
hasAsyncDisposable,
54+
isAsync: false,
55+
$"{Names.OnDisposeExceptionMethodName}(disposableInstance, exception)",
56+
$"{Names.OnDisposeAsyncExceptionMethodName}(asyncDisposableInstance, exception)");
7157
}
7258
}
7359

@@ -97,32 +83,17 @@ public CompositionCode Build(CompositionCode composition)
9783
code.AppendLine($"{composition.Source.Source.Hints.DisposeAsyncMethodModifiers} async {Names.ValueTaskTypeName} DisposeAsync()");
9884
using (code.CreateBlock())
9985
{
100-
AddSyncPart(composition, code, true, rootDisposablesCount, hasStateObjectScope, hasScopedLifetimes, singletonFieldsToReset);
86+
AddSyncPart(composition, code, true, rootDisposablesCount, hasStateObjectScope, hasScopedLifetimes, hasAsyncDisposable, singletonFieldsToReset);
10187
if (rootDisposablesCount > 0)
10288
{
10389
code.AppendLine();
104-
code.AppendLine("while (disposeIndex-- > 0)");
105-
using (code.CreateBlock())
106-
{
107-
code.AppendLine("switch (disposables[disposeIndex])");
108-
using (code.CreateBlock())
109-
{
110-
if (hasAsyncDisposable)
111-
{
112-
AddDisposeAsyncPart(code, true);
113-
}
114-
115-
if (hasDisposable)
116-
{
117-
if (hasAsyncDisposable)
118-
{
119-
code.AppendLine();
120-
}
121-
122-
AddDisposePart(code);
123-
}
124-
}
125-
}
90+
disposalStatementsBuilder.AddDisposeLoop(
91+
code,
92+
hasDisposable,
93+
hasAsyncDisposable,
94+
isAsync: true,
95+
$"{Names.OnDisposeExceptionMethodName}(disposableInstance, exception)",
96+
$"{Names.OnDisposeAsyncExceptionMethodName}(asyncDisposableInstance, exception)");
12697
}
12798
}
12899

@@ -142,72 +113,26 @@ public CompositionCode Build(CompositionCode composition)
142113
return composition with { MembersCount = membersCounter };
143114
}
144115

145-
private static void AddDisposeAsyncPart(Lines code, bool makeAsyncCall)
146-
{
147-
code.AppendLine($"case {Names.IAsyncDisposableTypeName} asyncDisposableInstance:");
148-
using (code.Indent())
149-
{
150-
code.AppendLine("try");
151-
using (code.CreateBlock())
152-
{
153-
if (makeAsyncCall)
154-
{
155-
code.AppendLine("await asyncDisposableInstance.DisposeAsync();");
156-
}
157-
else
158-
{
159-
code.AppendLine("var valueTask = asyncDisposableInstance.DisposeAsync();");
160-
code.AppendLine("if (!valueTask.IsCompleted)");
161-
using (code.CreateBlock())
162-
{
163-
code.AppendLine("valueTask.AsTask().Wait();");
164-
}
165-
}
166-
}
167-
168-
code.AppendLine($"catch ({Names.ExceptionTypeName} exception)");
169-
using (code.CreateBlock())
170-
{
171-
code.AppendLine($"{Names.OnDisposeAsyncExceptionMethodName}(asyncDisposableInstance, exception);");
172-
}
173-
174-
code.AppendLine("break;");
175-
}
176-
}
177-
178-
private static void AddDisposePart(Lines code)
179-
{
180-
code.AppendLine($"case {Names.IDisposableTypeName} disposableInstance:");
181-
using (code.Indent())
182-
{
183-
code.AppendLine("try");
184-
using (code.CreateBlock())
185-
{
186-
code.AppendLine("disposableInstance.Dispose();");
187-
}
188-
189-
code.AppendLine($"catch ({Names.ExceptionTypeName} exception)");
190-
using (code.CreateBlock())
191-
{
192-
code.AppendLine($"{Names.OnDisposeExceptionMethodName}(disposableInstance, exception);");
193-
}
194-
195-
code.AppendLine("break;");
196-
}
197-
}
198-
199116
private void AddSyncPart(
200117
CompositionCode composition,
201118
Lines code,
202119
bool isAsync,
203120
int rootDisposablesCount,
204121
bool hasStateObjectScope,
205122
bool hasScopedLifetimes,
123+
bool hasAsyncDisposables,
206124
ImmutableArray<VarDeclaration> singletonFieldsToReset)
207125
{
208126
if (hasStateObjectScope && hasScopedLifetimes)
209127
{
210-
code.AppendLine($"{Names.RootScopeFieldName}.Dispose();");
128+
if (isAsync && hasAsyncDisposables)
129+
{
130+
code.AppendLine($"await {Names.RootScopeFieldName}.DisposeAsync();");
131+
}
132+
else
133+
{
134+
code.AppendLine($"{Names.RootScopeFieldName}.Dispose();");
135+
}
211136
}
212137

213138
if (rootDisposablesCount > 0)

0 commit comments

Comments
 (0)