csharpc-sharpdotnetxamlavaloniauicross-platformcross-platform-xamlavaloniaguimulti-platformuser-interfacedotnetcore
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
545 lines
32 KiB
545 lines
32 KiB
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
using Microsoft.CodeAnalysis.CSharp;
|
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
|
|
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
|
|
|
|
|
|
namespace Tmds.DBus.SourceGenerator
|
|
{
|
|
public partial class DBusSourceGenerator
|
|
{
|
|
private ClassDeclarationSyntax GenerateProxy(DBusInterface dBusInterface)
|
|
{
|
|
string identifier = Pascalize(dBusInterface.Name!);
|
|
ClassDeclarationSyntax cl = ClassDeclaration(identifier)
|
|
.AddModifiers(Token(SyntaxKind.InternalKeyword));
|
|
|
|
FieldDeclarationSyntax interfaceConst = MakePrivateStringConst("Interface", dBusInterface.Name!, PredefinedType(Token(SyntaxKind.StringKeyword)));
|
|
FieldDeclarationSyntax connectionField = MakePrivateReadOnlyField("_connection", IdentifierName("Connection"));
|
|
FieldDeclarationSyntax destinationField = MakePrivateReadOnlyField("_destination", PredefinedType(Token(SyntaxKind.StringKeyword)));
|
|
FieldDeclarationSyntax pathField = MakePrivateReadOnlyField("_path", PredefinedType(Token(SyntaxKind.StringKeyword)));
|
|
|
|
ConstructorDeclarationSyntax ctor = ConstructorDeclaration(identifier)
|
|
.AddModifiers(Token(SyntaxKind.PublicKeyword))
|
|
.AddParameterListParameters(
|
|
Parameter(Identifier("connection"))
|
|
.WithType(IdentifierName("Connection")),
|
|
Parameter(Identifier("destination"))
|
|
.WithType(
|
|
PredefinedType(Token(SyntaxKind.StringKeyword))),
|
|
Parameter(Identifier("path"))
|
|
.WithType(
|
|
PredefinedType(Token(SyntaxKind.StringKeyword))))
|
|
.WithBody(
|
|
Block(
|
|
MakeAssignmentExpressionStatement("_connection", "connection"),
|
|
MakeAssignmentExpressionStatement("_destination", "destination"),
|
|
MakeAssignmentExpressionStatement("_path", "path")));
|
|
|
|
cl = cl.AddMembers(interfaceConst, connectionField, destinationField, pathField, ctor);
|
|
|
|
AddProperties(ref cl, dBusInterface);
|
|
AddProxyMethods(ref cl, dBusInterface);
|
|
AddProxySignals(ref cl, dBusInterface);
|
|
|
|
return cl;
|
|
}
|
|
|
|
private void AddProxyMethods(ref ClassDeclarationSyntax cl, DBusInterface dBusInterface)
|
|
{
|
|
if (dBusInterface.Methods is null)
|
|
return;
|
|
|
|
foreach (DBusMethod dBusMethod in dBusInterface.Methods)
|
|
{
|
|
DBusArgument[]? inArgs = dBusMethod.Arguments?.Where(static m => m.Direction is null or "in").ToArray();
|
|
DBusArgument[]? outArgs = dBusMethod.Arguments?.Where(static m => m.Direction == "out").ToArray();
|
|
|
|
ArgumentListSyntax args = ArgumentList(
|
|
SingletonSeparatedList(
|
|
Argument(
|
|
InvocationExpression(
|
|
IdentifierName("CreateMessage")))));
|
|
|
|
if (outArgs?.Length > 0)
|
|
{
|
|
args = args.AddArguments(
|
|
Argument(
|
|
MakeMemberAccessExpression("ReaderExtensions", GetOrAddReadMessageMethod(outArgs))));
|
|
}
|
|
|
|
StatementSyntax[] statements = inArgs?.Select((arg, i) => ExpressionStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("writer", GetOrAddWriteMethod(arg)))
|
|
.AddArgumentListArguments(
|
|
Argument(IdentifierName(arg.Name is not null ? SanitizeIdentifier(Camelize(arg.Name)) : $"arg{i}")))))
|
|
.Cast<StatementSyntax>()
|
|
.ToArray() ?? [];
|
|
|
|
BlockSyntax createMessageBody = MakeCreateMessageBody(IdentifierName("Interface"), dBusMethod.Name!, ParseSignature(inArgs), statements);
|
|
|
|
MethodDeclarationSyntax proxyMethod = MethodDeclaration(ParseTaskReturnType(outArgs, AccessMode.Read), $"{Pascalize(dBusMethod.Name!)}Async")
|
|
.AddModifiers(Token(SyntaxKind.PublicKeyword));
|
|
|
|
if (inArgs is not null)
|
|
proxyMethod = proxyMethod.WithParameterList(ParseParameterList(inArgs, AccessMode.Write));
|
|
|
|
cl = cl.AddMembers(proxyMethod.WithBody(MakeCallMethodReturnBody(args, createMessageBody)));
|
|
}
|
|
}
|
|
|
|
private void AddProxySignals(ref ClassDeclarationSyntax cl, DBusInterface dBusInterface)
|
|
{
|
|
if (dBusInterface.Signals is null)
|
|
return;
|
|
|
|
foreach (DBusSignal dBusSignal in dBusInterface.Signals)
|
|
{
|
|
DBusArgument[]? outArgs = dBusSignal.Arguments?.Where(static x => x.Direction is null or "out").ToArray();
|
|
TypeSyntax? returnType = ParseReturnType(outArgs, AccessMode.Read);
|
|
|
|
ParameterListSyntax parameters = ParameterList();
|
|
|
|
parameters = returnType is not null
|
|
? parameters.AddParameters(
|
|
Parameter(Identifier("handler"))
|
|
.WithType(
|
|
GenericName("Action")
|
|
.AddTypeArgumentListArguments(
|
|
NullableType(
|
|
IdentifierName("Exception")),
|
|
returnType)))
|
|
: parameters.AddParameters(
|
|
Parameter(Identifier("handler"))
|
|
.WithType(
|
|
GenericName("Action")
|
|
.AddTypeArgumentListArguments(
|
|
NullableType(
|
|
IdentifierName("Exception")))));
|
|
|
|
parameters = parameters.AddParameters(
|
|
Parameter(Identifier("emitOnCapturedContext"))
|
|
.WithType(PredefinedType(Token(SyntaxKind.BoolKeyword)))
|
|
.WithDefault(EqualsValueClause(LiteralExpression(SyntaxKind.TrueLiteralExpression))),
|
|
Parameter(Identifier("flags"))
|
|
.WithType(IdentifierName("ObserverFlags"))
|
|
.WithDefault(EqualsValueClause(MakeMemberAccessExpression("ObserverFlags", "None"))));
|
|
|
|
ArgumentListSyntax arguments = ArgumentList()
|
|
.AddArguments(
|
|
Argument(IdentifierName("_connection")),
|
|
Argument(IdentifierName("rule")));
|
|
|
|
if (outArgs is not null)
|
|
{
|
|
arguments = arguments.AddArguments(
|
|
Argument(
|
|
MakeMemberAccessExpression("ReaderExtensions", GetOrAddReadMessageMethod(outArgs))));
|
|
}
|
|
|
|
arguments = arguments.AddArguments(
|
|
Argument(IdentifierName("handler")),
|
|
Argument(IdentifierName("emitOnCapturedContext")),
|
|
Argument(IdentifierName("flags")));
|
|
|
|
MethodDeclarationSyntax watchSignalMethod = MethodDeclaration(
|
|
GenericName("ValueTask")
|
|
.AddTypeArgumentListArguments(
|
|
IdentifierName("IDisposable")),
|
|
$"Watch{Pascalize(dBusSignal.Name!)}Async")
|
|
.AddModifiers(Token(SyntaxKind.PublicKeyword))
|
|
.WithParameterList(parameters)
|
|
.WithBody(
|
|
Block(
|
|
LocalDeclarationStatement(
|
|
VariableDeclaration(IdentifierName("MatchRule"))
|
|
.AddVariables(
|
|
VariableDeclarator("rule")
|
|
.WithInitializer(
|
|
EqualsValueClause(MakeMatchRule(dBusSignal))))),
|
|
ReturnStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("SignalHelper", "WatchSignalAsync"))
|
|
.WithArgumentList(arguments))));
|
|
|
|
cl = cl.AddMembers(watchSignalMethod);
|
|
}
|
|
}
|
|
|
|
private static ObjectCreationExpressionSyntax MakeMatchRule(DBusSignal dBusSignal) =>
|
|
ObjectCreationExpression(IdentifierName("MatchRule"))
|
|
.WithInitializer(
|
|
InitializerExpression(SyntaxKind.ObjectInitializerExpression)
|
|
.AddExpressions(
|
|
MakeAssignmentExpression(IdentifierName("Type"), MakeMemberAccessExpression("MessageType", "Signal")),
|
|
MakeAssignmentExpression(IdentifierName("Sender"), IdentifierName("_destination")),
|
|
MakeAssignmentExpression(IdentifierName("Path"), IdentifierName("_path")),
|
|
MakeAssignmentExpression(IdentifierName("Member"), MakeLiteralExpression(dBusSignal.Name!)),
|
|
MakeAssignmentExpression(IdentifierName("Interface"), IdentifierName("Interface"))));
|
|
|
|
private void AddWatchPropertiesChanged(ref ClassDeclarationSyntax cl) =>
|
|
cl = cl.AddMembers(
|
|
MethodDeclaration(
|
|
GenericName("ValueTask")
|
|
.AddTypeArgumentListArguments(
|
|
IdentifierName("IDisposable")),
|
|
"WatchPropertiesChangedAsync")
|
|
.AddModifiers(Token(SyntaxKind.PublicKeyword))
|
|
.AddParameterListParameters(
|
|
Parameter(Identifier("handler"))
|
|
.WithType(GenericName("Action")
|
|
.AddTypeArgumentListArguments(
|
|
NullableType(
|
|
IdentifierName("Exception")),
|
|
GenericName("PropertyChanges")
|
|
.AddTypeArgumentListArguments(
|
|
IdentifierName("Properties")))),
|
|
Parameter(Identifier("emitOnCapturedContext"))
|
|
.WithType(PredefinedType(Token(SyntaxKind.BoolKeyword)))
|
|
.WithDefault(
|
|
EqualsValueClause(
|
|
LiteralExpression(SyntaxKind.TrueLiteralExpression))),
|
|
Parameter(Identifier("flags"))
|
|
.WithType(IdentifierName("ObserverFlags"))
|
|
.WithDefault(
|
|
EqualsValueClause(
|
|
MakeMemberAccessExpression("ObserverFlags", "None"))))
|
|
.WithBody(
|
|
Block(
|
|
ReturnStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("SignalHelper", "WatchPropertiesChangedAsync"))
|
|
.AddArgumentListArguments(
|
|
Argument(IdentifierName("_connection")),
|
|
Argument(IdentifierName("_destination")),
|
|
Argument(IdentifierName("_path")),
|
|
Argument(IdentifierName("Interface")),
|
|
Argument(IdentifierName("ReadMessage")),
|
|
Argument(IdentifierName("handler")),
|
|
Argument(IdentifierName("emitOnCapturedContext")),
|
|
Argument(IdentifierName("flags")))),
|
|
LocalFunctionStatement(
|
|
GenericName("PropertyChanges")
|
|
.AddTypeArgumentListArguments(
|
|
IdentifierName("Properties")),
|
|
"ReadMessage")
|
|
.AddModifiers(Token(SyntaxKind.StaticKeyword))
|
|
.AddParameterListParameters(
|
|
Parameter(Identifier("message"))
|
|
.WithType(IdentifierName("Message")),
|
|
Parameter(Identifier("_"))
|
|
.WithType(
|
|
NullableType(
|
|
PredefinedType(Token(SyntaxKind.ObjectKeyword)))))
|
|
.WithBody(
|
|
Block(
|
|
LocalDeclarationStatement(
|
|
VariableDeclaration(IdentifierName("Reader"))
|
|
.AddVariables(
|
|
VariableDeclarator("reader")
|
|
.WithInitializer(
|
|
EqualsValueClause(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("message", "GetBodyReader")))))),
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("reader", "ReadString"))),
|
|
LocalDeclarationStatement(
|
|
VariableDeclaration(
|
|
GenericName("List")
|
|
.AddTypeArgumentListArguments(
|
|
PredefinedType(Token(SyntaxKind.StringKeyword))))
|
|
.AddVariables(
|
|
VariableDeclarator("changed")
|
|
.WithInitializer(
|
|
EqualsValueClause(
|
|
ImplicitObjectCreationExpression())))),
|
|
ReturnStatement(
|
|
InvocationExpression(
|
|
ObjectCreationExpression(GenericName("PropertyChanges")
|
|
.AddTypeArgumentListArguments(
|
|
IdentifierName("Properties"))))
|
|
.AddArgumentListArguments(
|
|
Argument(InvocationExpression(
|
|
IdentifierName("ReadProperties"))
|
|
.AddArgumentListArguments(
|
|
Argument(IdentifierName("reader"))
|
|
.WithRefKindKeyword(Token(SyntaxKind.RefKeyword)),
|
|
Argument(IdentifierName("changed")))),
|
|
Argument(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("changed", "ToArray"))),
|
|
Argument(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("reader",
|
|
GetOrAddReadMethod(new DBusValue { Type = "as" })))))))))));
|
|
|
|
private void AddProperties(ref ClassDeclarationSyntax cl, DBusInterface dBusInterface)
|
|
{
|
|
if (dBusInterface.Properties is null || dBusInterface.Properties.Length == 0)
|
|
return;
|
|
|
|
cl = dBusInterface.Properties!.Aggregate(cl, (current, dBusProperty) => dBusProperty.Access switch
|
|
{
|
|
"read" => current.AddMembers(MakeGetMethod(dBusProperty)),
|
|
"write" => current.AddMembers(MakeSetMethod(dBusProperty)),
|
|
"readwrite" => current.AddMembers(MakeGetMethod(dBusProperty), MakeSetMethod(dBusProperty)),
|
|
_ => current
|
|
});
|
|
|
|
AddGetAllMethod(ref cl);
|
|
AddReadProperties(ref cl, dBusInterface.Properties);
|
|
AddPropertiesClass(ref cl, dBusInterface);
|
|
AddWatchPropertiesChanged(ref cl);
|
|
}
|
|
|
|
private MethodDeclarationSyntax MakeGetMethod(DBusProperty dBusProperty)
|
|
{
|
|
BlockSyntax createMessageBody = MakeCreateMessageBody(MakeLiteralExpression("org.freedesktop.DBus.Properties"), "Get", "ss",
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("writer", "WriteString"))
|
|
.AddArgumentListArguments(Argument(IdentifierName("Interface")))),
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("writer", "WriteString"))
|
|
.AddArgumentListArguments(Argument(MakeLiteralExpression(dBusProperty.Name!)))));
|
|
|
|
ArgumentListSyntax args = ArgumentList()
|
|
.AddArguments(
|
|
Argument(
|
|
InvocationExpression(
|
|
IdentifierName("CreateMessage"))),
|
|
Argument(
|
|
MakeMemberAccessExpression("ReaderExtensions", GetOrAddReadMessageMethod(dBusProperty, true))));
|
|
|
|
return MethodDeclaration(ParseTaskReturnType([dBusProperty], AccessMode.Read), $"Get{Pascalize(dBusProperty.Name!)}PropertyAsync")
|
|
.AddModifiers(Token(SyntaxKind.PublicKeyword))
|
|
.WithBody(
|
|
MakeCallMethodReturnBody(args, createMessageBody));
|
|
}
|
|
|
|
private static MethodDeclarationSyntax MakeSetMethod(DBusProperty dBusProperty)
|
|
{
|
|
BlockSyntax createMessageBody = MakeCreateMessageBody(MakeLiteralExpression("org.freedesktop.DBus.Properties"), "Set", "ssv",
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("writer", "WriteString"))
|
|
.AddArgumentListArguments(Argument(IdentifierName("Interface")))),
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("writer", "WriteString"))
|
|
.AddArgumentListArguments(Argument(MakeLiteralExpression(Pascalize(dBusProperty.Name!))))),
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("writer", "WriteVariant"))
|
|
.AddArgumentListArguments(Argument(IdentifierName("value")))));
|
|
|
|
ArgumentListSyntax args = ArgumentList(
|
|
SingletonSeparatedList(
|
|
Argument(
|
|
InvocationExpression(
|
|
IdentifierName("CreateMessage")))));
|
|
|
|
return MethodDeclaration(
|
|
IdentifierName("Task"),
|
|
$"Set{Pascalize(dBusProperty.Name!)}PropertyAsync")
|
|
.AddModifiers(Token(SyntaxKind.PublicKeyword))
|
|
.AddParameterListParameters(
|
|
Parameter(Identifier("value"))
|
|
.WithType(GetDotnetType(dBusProperty, AccessMode.Write)))
|
|
.WithBody(
|
|
MakeCallMethodReturnBody(args, createMessageBody));
|
|
}
|
|
|
|
private static void AddGetAllMethod(ref ClassDeclarationSyntax cl)
|
|
{
|
|
BlockSyntax createGetAllMessageBody = MakeCreateMessageBody(MakeLiteralExpression("org.freedesktop.DBus.Properties"), "GetAll", "s",
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("writer", "WriteString"))
|
|
.AddArgumentListArguments(Argument(IdentifierName("Interface")))));
|
|
|
|
ParenthesizedLambdaExpressionSyntax messageValueReaderLambda = ParenthesizedLambdaExpression()
|
|
.AddParameterListParameters(
|
|
Parameter(Identifier("message"))
|
|
.WithType(IdentifierName("Message")),
|
|
Parameter(Identifier("state"))
|
|
.WithType(
|
|
NullableType(PredefinedType(Token(SyntaxKind.ObjectKeyword)))))
|
|
.WithBody(
|
|
Block(
|
|
LocalDeclarationStatement(
|
|
VariableDeclaration(IdentifierName("Reader"))
|
|
.AddVariables(
|
|
VariableDeclarator("reader")
|
|
.WithInitializer(
|
|
EqualsValueClause(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("message", "GetBodyReader")))))),
|
|
ReturnStatement(
|
|
InvocationExpression(
|
|
IdentifierName("ReadProperties"))
|
|
.AddArgumentListArguments(
|
|
Argument(IdentifierName("reader"))
|
|
.WithRefKindKeyword(Token(SyntaxKind.RefKeyword))))));
|
|
|
|
cl = cl.AddMembers(
|
|
MethodDeclaration(
|
|
GenericName("Task")
|
|
.AddTypeArgumentListArguments(
|
|
IdentifierName("Properties")),
|
|
"GetAllPropertiesAsync")
|
|
.AddModifiers(Token(SyntaxKind.PublicKeyword))
|
|
.WithBody(
|
|
Block(
|
|
ReturnStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("_connection", "CallMethodAsync"))
|
|
.AddArgumentListArguments(
|
|
Argument(
|
|
InvocationExpression(IdentifierName("CreateGetAllMessage"))),
|
|
Argument(messageValueReaderLambda))),
|
|
LocalFunctionStatement(IdentifierName("MessageBuffer"), "CreateGetAllMessage")
|
|
.WithBody(createGetAllMessageBody))));
|
|
}
|
|
|
|
private static void AddPropertiesClass(ref ClassDeclarationSyntax cl, DBusInterface dBusInterface)
|
|
{
|
|
ClassDeclarationSyntax propertiesClass = ClassDeclaration("Properties")
|
|
.AddModifiers(Token(SyntaxKind.PublicKeyword));
|
|
|
|
propertiesClass = dBusInterface.Properties!.Aggregate(propertiesClass, static (current, property) =>
|
|
current.AddMembers(
|
|
MakeGetSetProperty(GetDotnetType(property, AccessMode.Read), Pascalize(property.Name!), Token(SyntaxKind.PublicKeyword))));
|
|
|
|
cl = cl.AddMembers(propertiesClass);
|
|
}
|
|
|
|
private void AddReadProperties(ref ClassDeclarationSyntax cl, IEnumerable<DBusProperty> dBusProperties) =>
|
|
cl = cl.AddMembers(
|
|
MethodDeclaration(
|
|
IdentifierName("Properties"), "ReadProperties")
|
|
.AddModifiers(Token(SyntaxKind.PrivateKeyword), Token(SyntaxKind.StaticKeyword))
|
|
.AddParameterListParameters(
|
|
Parameter(Identifier("reader"))
|
|
.WithType(IdentifierName("Reader"))
|
|
.AddModifiers(Token(SyntaxKind.RefKeyword)),
|
|
Parameter(Identifier("changed"))
|
|
.WithType(
|
|
NullableType(
|
|
GenericName("List")
|
|
.AddTypeArgumentListArguments(
|
|
PredefinedType(Token(SyntaxKind.StringKeyword)))))
|
|
.WithDefault(
|
|
EqualsValueClause(
|
|
LiteralExpression(SyntaxKind.NullLiteralExpression))))
|
|
.WithBody(
|
|
Block(
|
|
LocalDeclarationStatement(VariableDeclaration(IdentifierName("Properties"))
|
|
.AddVariables(
|
|
VariableDeclarator("props")
|
|
.WithInitializer(
|
|
EqualsValueClause(
|
|
InvocationExpression(
|
|
ObjectCreationExpression(IdentifierName("Properties"))))))),
|
|
LocalDeclarationStatement(VariableDeclaration(IdentifierName("ArrayEnd"))
|
|
.AddVariables(
|
|
VariableDeclarator("headersEnd")
|
|
.WithInitializer(
|
|
EqualsValueClause(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("reader", "ReadArrayStart"))
|
|
.AddArgumentListArguments(
|
|
Argument(MakeMemberAccessExpression("DBusType", "Struct"))))))),
|
|
WhileStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("reader", "HasNext"))
|
|
.AddArgumentListArguments(Argument(IdentifierName("headersEnd"))),
|
|
Block(
|
|
SwitchStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("reader", "ReadString")))
|
|
.WithSections(
|
|
List(
|
|
dBusProperties.Select(property => SwitchSection()
|
|
.AddLabels(
|
|
CaseSwitchLabel(
|
|
MakeLiteralExpression(property.Name!)))
|
|
.AddStatements(
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("reader", "ReadSignature"))
|
|
.AddArgumentListArguments(
|
|
Argument(
|
|
MakeLiteralExpression(property.Type!)))),
|
|
ExpressionStatement(
|
|
AssignmentExpression(SyntaxKind.SimpleAssignmentExpression,
|
|
MakeMemberAccessExpression("props", Pascalize(property.Name!)),
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("reader", GetOrAddReadMethod(property))))),
|
|
ExpressionStatement(
|
|
ConditionalAccessExpression(
|
|
IdentifierName("changed"), InvocationExpression(
|
|
MemberBindingExpression(
|
|
IdentifierName("Add")))
|
|
.AddArgumentListArguments(
|
|
Argument(
|
|
MakeLiteralExpression(Pascalize(property.Name!)))))),
|
|
BreakStatement())))))),
|
|
ReturnStatement(IdentifierName("props")))));
|
|
|
|
private static BlockSyntax MakeCallMethodReturnBody(ArgumentListSyntax args, BlockSyntax createMessageBody) =>
|
|
Block(
|
|
ReturnStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("_connection", "CallMethodAsync"))
|
|
.WithArgumentList(args)),
|
|
LocalFunctionStatement(IdentifierName("MessageBuffer"), "CreateMessage")
|
|
.WithBody(createMessageBody));
|
|
|
|
private static BlockSyntax MakeCreateMessageBody(ExpressionSyntax interfaceExpression, string methodName, string? signature, params StatementSyntax[] statements)
|
|
{
|
|
ArgumentListSyntax args = ArgumentList()
|
|
.AddArguments(
|
|
Argument(IdentifierName("_destination")),
|
|
Argument(IdentifierName("_path")),
|
|
Argument(interfaceExpression),
|
|
Argument(MakeLiteralExpression(methodName)));
|
|
|
|
if (signature is not null)
|
|
args = args.AddArguments(Argument(MakeLiteralExpression(signature)));
|
|
|
|
return Block(
|
|
LocalDeclarationStatement(
|
|
VariableDeclaration(IdentifierName("MessageWriter"),
|
|
SingletonSeparatedList(
|
|
VariableDeclarator("writer")
|
|
.WithInitializer(EqualsValueClause(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("_connection", "GetMessageWriter"))))))),
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("writer", "WriteMethodCallHeader"))
|
|
.WithArgumentList(args)))
|
|
.AddStatements(statements)
|
|
.AddStatements(
|
|
LocalDeclarationStatement(
|
|
VariableDeclaration(IdentifierName("MessageBuffer"))
|
|
.AddVariables(
|
|
VariableDeclarator("message")
|
|
.WithInitializer(
|
|
EqualsValueClause(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("writer", "CreateMessage")))))),
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("writer", "Dispose"))),
|
|
ReturnStatement(
|
|
IdentifierName("message")));
|
|
}
|
|
}
|
|
}
|
|
|