Skip to content

Commit 8bbf5b8

Browse files
[RGen] Refactor EmitMethods to allow to emit a single method. (#23425)
This will come useful when we want to emit protocols in such a way that we have: - Getter method - Setter method - Property This way we mimic the way bgen generates this methods.
1 parent 5b303ed commit 8bbf5b8

File tree

1 file changed

+59
-36
lines changed

1 file changed

+59
-36
lines changed

src/rgen/Microsoft.Macios.Generator/Emitters/ClassEmitterExtensions.cs

Lines changed: 59 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Collections.Immutable;
55
using System.IO;
66
using System.Linq;
7+
using Microsoft.CodeAnalysis.CSharp.Syntax;
78
using Microsoft.Macios.Generator.Context;
89
using Microsoft.Macios.Generator.DataModel;
910
using Microsoft.Macios.Generator.Extensions;
@@ -168,56 +169,78 @@ static void EmitReturnMethodBody (in Method method, in MethodInvocations invocat
168169
}
169170

170171
/// <summary>
171-
/// Emit the code for all the methods in the class.
172+
/// Emits the code for a given method, including its async version if applicable.
172173
/// </summary>
174+
/// <param name="self">The class emitter.</param>
173175
/// <param name="context">The current binding context.</param>
174-
/// <param name="classBlock">Current class block.</param>
175-
public static void EmitMethods (this IClassEmitter self, in BindingContext context, TabbedWriter<StringWriter> classBlock)
176+
/// <param name="method">The method to emit.</param>
177+
/// <param name="classBlock">The current class block writer.</param>
178+
/// <param name="uiThreadCheck">An optional UI thread check expression. If not provided, it will be created based on the context.</param>
179+
public static void EmitMethod (this IClassEmitter self, in BindingContext context, in Method method,
180+
TabbedWriter<StringWriter> classBlock, ExpressionStatementSyntax? uiThreadCheck = null)
176181
{
177-
var uiThreadCheck = (context.NeedsThreadChecks)
178-
? EnsureUiThread (context.RootContext.CurrentPlatform) : null;
179-
foreach (var method in context.Changes.Methods.OrderBy (m => m.Name)) {
180-
classBlock.WriteLine ();
181-
classBlock.AppendMemberAvailability (method.SymbolAvailability);
182-
classBlock.AppendGeneratedCodeAttribute (optimizable: true);
183182

184-
using (var methodBlock = classBlock.CreateBlock (method.ToDeclaration ().ToString (), block: true)) {
185-
// write any possible thread check at the beginning of the method
186-
if (uiThreadCheck is not null) {
187-
methodBlock.WriteLine (uiThreadCheck.ToString ());
188-
methodBlock.WriteLine ();
189-
}
183+
// if not passed as an argument, we will create the ui thread check based on the context
184+
if (uiThreadCheck is null) {
185+
uiThreadCheck = (context.NeedsThreadChecks)
186+
? EnsureUiThread (context.RootContext.CurrentPlatform)
187+
: null;
188+
}
190189

191-
// retrieve the method invocation via the factory, this will generate the necessary arguments
192-
// transformations and the invocation
193-
var invocations = GetInvocations (method);
190+
classBlock.WriteLine ();
191+
classBlock.AppendMemberAvailability (method.SymbolAvailability);
192+
classBlock.AppendGeneratedCodeAttribute (optimizable: true);
194193

195-
if (method.ReturnType.IsVoid) {
196-
EmitVoidMethodBody (method, invocations, methodBlock);
197-
} else {
198-
EmitReturnMethodBody (method, invocations, methodBlock);
199-
}
194+
using (var methodBlock = classBlock.CreateBlock (method.ToDeclaration ().ToString (), block: true)) {
195+
// write any possible thread check at the beginning of the method
196+
if (uiThreadCheck is not null) {
197+
methodBlock.WriteLine (uiThreadCheck.ToString ());
198+
methodBlock.WriteLine ();
200199
}
201200

202-
if (!method.IsAsync)
203-
continue;
201+
// retrieve the method invocation via the factory, this will generate the necessary arguments
202+
// transformations and the invocation
203+
var invocations = GetInvocations (method);
204204

205-
// if the method is an async method, generate its async version
206-
classBlock.WriteLine ();
207-
classBlock.AppendMemberAvailability (method.SymbolAvailability);
208-
classBlock.AppendGeneratedCodeAttribute (optimizable: true);
205+
if (method.ReturnType.IsVoid) {
206+
EmitVoidMethodBody (method, invocations, methodBlock);
207+
} else {
208+
EmitReturnMethodBody (method, invocations, methodBlock);
209+
}
210+
}
211+
212+
if (!method.IsAsync)
213+
return;
209214

210-
var asyncMethod = method.ToAsync ();
211-
using (var methodBlock = classBlock.CreateBlock (asyncMethod.ToDeclaration ().ToString (), block: true)) {
212-
// we need to create the tcs for the the async method
213-
var tcsType = asyncMethod.ReturnType.ToTaskCompletionSource ();
214-
var tcsName = Nomenclator.GetTaskCompletionSourceName ();
215-
methodBlock.WriteRaw (
215+
// if the method is an async method, generate its async version
216+
classBlock.WriteLine ();
217+
classBlock.AppendMemberAvailability (method.SymbolAvailability);
218+
classBlock.AppendGeneratedCodeAttribute (optimizable: true);
219+
220+
var asyncMethod = method.ToAsync ();
221+
using (var methodBlock = classBlock.CreateBlock (asyncMethod.ToDeclaration ().ToString (), block: true)) {
222+
// we need to create the tcs for the the async method
223+
var tcsType = asyncMethod.ReturnType.ToTaskCompletionSource ();
224+
var tcsName = Nomenclator.GetTaskCompletionSourceName ();
225+
methodBlock.WriteRaw (
216226
$@"{tcsType.GetIdentifierSyntax ()} {tcsName} = new ();
217227
{ExpressionStatement (ExecuteSyncCall (method))}
218228
return {tcsName}.Task;
219229
");
220-
}
230+
}
231+
}
232+
233+
/// <summary>
234+
/// Emit the code for all the methods in the class.
235+
/// </summary>
236+
/// <param name="context">The current binding context.</param>
237+
/// <param name="classBlock">Current class block.</param>
238+
public static void EmitMethods (this IClassEmitter self, in BindingContext context, TabbedWriter<StringWriter> classBlock)
239+
{
240+
var uiThreadCheck = (context.NeedsThreadChecks)
241+
? EnsureUiThread (context.RootContext.CurrentPlatform) : null;
242+
foreach (var method in context.Changes.Methods.OrderBy (m => m.Name)) {
243+
EmitMethod (self, context, method, classBlock, uiThreadCheck);
221244
}
222245
}
223246

0 commit comments

Comments
 (0)