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.
624 lines
37 KiB
624 lines
37 KiB
using System.IO;
|
|
using System.Linq;
|
|
using System.Xml;
|
|
using System.Xml.Serialization;
|
|
|
|
using Microsoft.CodeAnalysis;
|
|
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 GenerateHandler(DBusInterface dBusInterface)
|
|
{
|
|
ClassDeclarationSyntax cl = ClassDeclaration(Pascalize(dBusInterface.Name!))
|
|
.AddModifiers(
|
|
Token(SyntaxKind.InternalKeyword),
|
|
Token(SyntaxKind.AbstractKeyword))
|
|
.AddBaseListTypes(
|
|
SimpleBaseType(
|
|
IdentifierName("IDBusInterfaceHandler")))
|
|
.AddMembers(
|
|
MakePrivateReadOnlyField(
|
|
"_synchronizationContext",
|
|
NullableType(
|
|
IdentifierName("SynchronizationContext"))),
|
|
ConstructorDeclaration(
|
|
Pascalize(dBusInterface.Name!))
|
|
.AddModifiers(
|
|
Token(SyntaxKind.PublicKeyword))
|
|
.AddParameterListParameters(
|
|
Parameter(
|
|
Identifier("emitOnCapturedContext"))
|
|
.WithType(
|
|
PredefinedType(
|
|
Token(SyntaxKind.BoolKeyword)))
|
|
.WithDefault(
|
|
EqualsValueClause(
|
|
LiteralExpression(SyntaxKind.TrueLiteralExpression))))
|
|
.WithBody(
|
|
Block(
|
|
IfStatement(
|
|
IdentifierName("emitOnCapturedContext"),
|
|
ExpressionStatement(
|
|
AssignmentExpression(SyntaxKind.SimpleAssignmentExpression,
|
|
IdentifierName("_synchronizationContext"),
|
|
MakeMemberAccessExpression("SynchronizationContext", "Current")))))),
|
|
MakeGetSetProperty(
|
|
NullableType(
|
|
IdentifierName("PathHandler")),
|
|
"PathHandler",
|
|
Token(SyntaxKind.PublicKeyword)),
|
|
MakeGetOnlyProperty(
|
|
IdentifierName("Connection"),
|
|
"Connection",
|
|
Token(SyntaxKind.PublicKeyword),
|
|
Token(SyntaxKind.AbstractKeyword)),
|
|
MakeGetOnlyProperty(
|
|
PredefinedType(
|
|
Token(SyntaxKind.StringKeyword)),
|
|
"InterfaceName",
|
|
Token(SyntaxKind.PublicKeyword))
|
|
.WithInitializer(
|
|
EqualsValueClause(
|
|
MakeLiteralExpression(dBusInterface.Name!)))
|
|
.WithSemicolonToken(
|
|
Token(SyntaxKind.SemicolonToken)));
|
|
|
|
AddHandlerProperties(ref cl, dBusInterface);
|
|
AddHandlerIntrospect(ref cl, dBusInterface);
|
|
AddHandlerMethods(ref cl, dBusInterface);
|
|
AddHandlerSignals(ref cl, dBusInterface);
|
|
|
|
return cl;
|
|
}
|
|
|
|
private void AddHandlerMethods(ref ClassDeclarationSyntax cl, DBusInterface dBusInterface)
|
|
{
|
|
if (dBusInterface.Methods is null)
|
|
return;
|
|
|
|
SyntaxList<SwitchSectionSyntax> switchSections = List<SwitchSectionSyntax>();
|
|
|
|
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();
|
|
|
|
SwitchSectionSyntax switchSection = SwitchSection()
|
|
.AddLabels(
|
|
CasePatternSwitchLabel(
|
|
RecursivePattern()
|
|
.WithPositionalPatternClause(
|
|
PositionalPatternClause()
|
|
.AddSubpatterns(
|
|
Subpattern(
|
|
ConstantPattern(
|
|
MakeLiteralExpression(dBusMethod.Name!))),
|
|
Subpattern(
|
|
inArgs?.Length > 0
|
|
? ConstantPattern(
|
|
MakeLiteralExpression(
|
|
ParseSignature(inArgs)!))
|
|
: BinaryPattern(SyntaxKind.OrPattern,
|
|
ConstantPattern(
|
|
MakeLiteralExpression(string.Empty)),
|
|
ConstantPattern(
|
|
LiteralExpression(SyntaxKind.NullLiteralExpression)))))),
|
|
Token(SyntaxKind.ColonToken)));
|
|
|
|
BlockSyntax switchSectionBlock = Block();
|
|
|
|
string abstractMethodName = $"On{Pascalize(dBusMethod.Name!)}Async";
|
|
|
|
MethodDeclarationSyntax abstractMethod = MethodDeclaration(
|
|
ParseValueTaskReturnType(outArgs, AccessMode.Write), abstractMethodName);
|
|
|
|
if (inArgs?.Length > 0)
|
|
abstractMethod = abstractMethod.WithParameterList(
|
|
ParseParameterList(inArgs, AccessMode.Read));
|
|
|
|
abstractMethod = abstractMethod
|
|
.AddModifiers(Token(SyntaxKind.ProtectedKeyword), Token(SyntaxKind.AbstractKeyword))
|
|
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken));
|
|
|
|
cl = cl.AddMembers(abstractMethod);
|
|
|
|
if (inArgs?.Length > 0)
|
|
{
|
|
BlockSyntax readParametersMethodBlock = Block(
|
|
LocalDeclarationStatement(
|
|
VariableDeclaration(IdentifierName("Reader"))
|
|
.AddVariables(
|
|
VariableDeclarator("reader")
|
|
.WithInitializer(
|
|
EqualsValueClause(
|
|
InvocationExpression(MakeMemberAccessExpression("context", "Request", "GetBodyReader")))))));
|
|
|
|
StatementSyntax[] argFields = new StatementSyntax[inArgs.Length];
|
|
|
|
for (int i = 0; i < inArgs.Length; i++)
|
|
{
|
|
string identifier = inArgs[i].Name is not null ? SanitizeIdentifier(Camelize(inArgs[i].Name!)) : $"arg{i}";
|
|
readParametersMethodBlock = readParametersMethodBlock.AddStatements(
|
|
ExpressionStatement(
|
|
AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, IdentifierName(identifier), InvocationExpression(
|
|
MakeMemberAccessExpression("reader", GetOrAddReadMethod(inArgs[i]))))));
|
|
argFields[i] = LocalDeclarationStatement(
|
|
VariableDeclaration(GetDotnetType(inArgs[i], AccessMode.Read))
|
|
.AddVariables(
|
|
VariableDeclarator(identifier)));
|
|
}
|
|
|
|
switchSectionBlock = switchSectionBlock.AddStatements(argFields);
|
|
switchSectionBlock = switchSectionBlock.AddStatements(
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
IdentifierName("ReadParameters"))),
|
|
LocalFunctionStatement(
|
|
PredefinedType(Token(SyntaxKind.VoidKeyword)), Identifier("ReadParameters"))
|
|
.WithBody(readParametersMethodBlock));
|
|
}
|
|
|
|
if (outArgs?.Length > 0)
|
|
{
|
|
switchSectionBlock = switchSectionBlock.AddStatements(
|
|
LocalDeclarationStatement(
|
|
VariableDeclaration(ParseReturnType(outArgs, AccessMode.Write)!)
|
|
.AddVariables(
|
|
VariableDeclarator("ret"))));
|
|
}
|
|
|
|
ExpressionSyntax callAbstractMethod = AwaitExpression(
|
|
InvocationExpression(
|
|
IdentifierName(abstractMethodName))
|
|
.AddArgumentListArguments(
|
|
inArgs?.Select(static (argument, i) =>
|
|
Argument(
|
|
IdentifierName(argument.Name is not null
|
|
? SanitizeIdentifier(Camelize(argument.Name))
|
|
: $"arg{i}")))
|
|
.ToArray() ?? []));
|
|
|
|
switchSectionBlock = switchSectionBlock.AddStatements(
|
|
IfStatement(
|
|
IsPatternExpression(
|
|
IdentifierName("_synchronizationContext"), UnaryPattern(ConstantPattern(LiteralExpression(SyntaxKind.NullLiteralExpression)))),
|
|
Block(
|
|
LocalDeclarationStatement(
|
|
VariableDeclaration(
|
|
ParseTaskCompletionSourceType(outArgs, AccessMode.Write))
|
|
.AddVariables(
|
|
VariableDeclarator("tsc")
|
|
.WithInitializer(
|
|
EqualsValueClause(
|
|
ImplicitObjectCreationExpression())))),
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("_synchronizationContext", "Post"))
|
|
.AddArgumentListArguments(
|
|
Argument(
|
|
SimpleLambdaExpression(
|
|
Parameter(
|
|
Identifier("_")))
|
|
.WithAsyncKeyword(Token(SyntaxKind.AsyncKeyword))
|
|
.WithBlock(
|
|
Block(
|
|
TryStatement()
|
|
.AddBlockStatements(
|
|
outArgs?.Length > 0
|
|
? LocalDeclarationStatement(
|
|
VariableDeclaration(
|
|
ParseReturnType(outArgs, AccessMode.Write)!)
|
|
.AddVariables(
|
|
VariableDeclarator("ret1")
|
|
.WithInitializer(
|
|
EqualsValueClause(callAbstractMethod))))
|
|
: ExpressionStatement(callAbstractMethod),
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("tsc", "SetResult"))
|
|
.AddArgumentListArguments(
|
|
Argument(
|
|
outArgs?.Length > 0
|
|
? IdentifierName("ret1")
|
|
: LiteralExpression(SyntaxKind.TrueLiteralExpression)))))
|
|
.AddCatches(
|
|
CatchClause()
|
|
.WithDeclaration(
|
|
CatchDeclaration(IdentifierName("Exception"))
|
|
.WithIdentifier(Identifier("e")))
|
|
.WithBlock(
|
|
Block(
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("tsc", "SetException"))
|
|
.AddArgumentListArguments(
|
|
Argument(IdentifierName("e")))))))))),
|
|
Argument(
|
|
LiteralExpression(SyntaxKind.NullLiteralExpression)))),
|
|
ExpressionStatement(
|
|
outArgs?.Length > 0
|
|
? MakeAssignmentExpression(
|
|
IdentifierName("ret"), AwaitExpression(
|
|
MakeMemberAccessExpression("tsc", "Task")))
|
|
: AwaitExpression(
|
|
MakeMemberAccessExpression("tsc", "Task")))),
|
|
ElseClause(
|
|
Block(
|
|
ExpressionStatement(
|
|
outArgs?.Length > 0
|
|
? MakeAssignmentExpression(
|
|
IdentifierName("ret"), callAbstractMethod)
|
|
: callAbstractMethod)))));
|
|
|
|
BlockSyntax replyMethodBlock = Block(
|
|
LocalDeclarationStatement(
|
|
VariableDeclaration(IdentifierName("MessageWriter"))
|
|
.AddVariables(
|
|
VariableDeclarator("writer")
|
|
.WithInitializer(
|
|
EqualsValueClause(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("context", "CreateReplyWriter"))
|
|
.AddArgumentListArguments(
|
|
Argument(
|
|
outArgs?.Length > 0
|
|
? MakeLiteralExpression(
|
|
ParseSignature(outArgs)!)
|
|
: LiteralExpression(SyntaxKind.NullLiteralExpression))))))));
|
|
|
|
if (outArgs?.Length == 1)
|
|
{
|
|
replyMethodBlock = replyMethodBlock.AddStatements(
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("writer", GetOrAddWriteMethod(outArgs[0])))
|
|
.AddArgumentListArguments(
|
|
Argument(
|
|
IdentifierName("ret")))));
|
|
}
|
|
else if (outArgs?.Length > 1)
|
|
{
|
|
for (int i = 0; i < outArgs.Length; i++)
|
|
{
|
|
replyMethodBlock = replyMethodBlock.AddStatements(
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("writer", GetOrAddWriteMethod(outArgs[i])))
|
|
.AddArgumentListArguments(
|
|
Argument(
|
|
MakeMemberAccessExpression("ret", outArgs[i].Name is not null
|
|
? SanitizeIdentifier(Pascalize(outArgs[i].Name!))
|
|
: $"Item{i + 1}")))));
|
|
}
|
|
}
|
|
|
|
replyMethodBlock = replyMethodBlock.AddStatements(
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("context", "Reply"))
|
|
.AddArgumentListArguments(
|
|
Argument(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("writer", "CreateMessage"))))),
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("writer", "Dispose"))));
|
|
|
|
switchSectionBlock = switchSectionBlock.AddStatements(
|
|
IfStatement(
|
|
PrefixUnaryExpression(SyntaxKind.LogicalNotExpression, MakeMemberAccessExpression("context", "NoReplyExpected")),
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
IdentifierName("Reply")))),
|
|
LocalFunctionStatement(
|
|
PredefinedType(Token(SyntaxKind.VoidKeyword)), Identifier("Reply"))
|
|
.WithBody(replyMethodBlock));
|
|
|
|
switchSections = switchSections.Add(
|
|
switchSection.AddStatements(
|
|
switchSectionBlock.AddStatements(
|
|
BreakStatement())));
|
|
}
|
|
|
|
cl = cl.AddMembers(
|
|
MethodDeclaration(
|
|
IdentifierName("ValueTask"),
|
|
"ReplyInterfaceRequest")
|
|
.AddModifiers(
|
|
Token(SyntaxKind.PublicKeyword),
|
|
Token(SyntaxKind.AsyncKeyword))
|
|
.AddParameterListParameters(
|
|
Parameter(
|
|
Identifier("context"))
|
|
.WithType(
|
|
IdentifierName("MethodContext")))
|
|
.WithBody(
|
|
Block(
|
|
SwitchStatement(
|
|
TupleExpression()
|
|
.AddArguments(
|
|
Argument(
|
|
MakeMemberAccessExpression("context", "Request", "MemberAsString")),
|
|
Argument(
|
|
MakeMemberAccessExpression("context", "Request", "SignatureAsString"))))
|
|
.WithSections(switchSections))));
|
|
}
|
|
|
|
private void AddHandlerProperties(ref ClassDeclarationSyntax cl, DBusInterface dBusInterface)
|
|
{
|
|
dBusInterface.Properties ??= [];
|
|
|
|
cl = dBusInterface.Properties!.Aggregate(cl, static (current, property) =>
|
|
current.AddMembers(
|
|
MakeGetSetProperty(
|
|
GetDotnetType(property, AccessMode.Write, true),
|
|
Pascalize(property.Name!), Token(SyntaxKind.PublicKeyword))));
|
|
|
|
cl = cl.AddMembers(
|
|
MethodDeclaration(
|
|
PredefinedType(
|
|
Token(SyntaxKind.VoidKeyword)),
|
|
"ReplyGetProperty")
|
|
.AddModifiers(
|
|
Token(SyntaxKind.PublicKeyword))
|
|
.AddParameterListParameters(
|
|
Parameter(
|
|
Identifier("name"))
|
|
.WithType(
|
|
PredefinedType(
|
|
Token(SyntaxKind.StringKeyword))),
|
|
Parameter(
|
|
Identifier("context"))
|
|
.WithType(
|
|
IdentifierName("MethodContext")))
|
|
.WithBody(
|
|
Block(
|
|
SwitchStatement(
|
|
IdentifierName("name"))
|
|
.WithSections(
|
|
List(
|
|
dBusInterface.Properties.Select(property =>
|
|
SwitchSection()
|
|
.AddLabels(
|
|
CaseSwitchLabel(
|
|
MakeLiteralExpression(property.Name!)))
|
|
.AddStatements(
|
|
Block(
|
|
LocalDeclarationStatement(
|
|
VariableDeclaration(IdentifierName("MessageWriter"))
|
|
.AddVariables(
|
|
VariableDeclarator("writer")
|
|
.WithInitializer(
|
|
EqualsValueClause(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("context", "CreateReplyWriter"))
|
|
.AddArgumentListArguments(
|
|
Argument(
|
|
MakeLiteralExpression("v"))))))),
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("writer", "WriteSignature"))
|
|
.AddArgumentListArguments(
|
|
Argument(
|
|
MakeLiteralExpression(property.Type!)))),
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("writer", GetOrAddWriteMethod(property)))
|
|
.AddArgumentListArguments(
|
|
Argument(
|
|
IdentifierName(
|
|
Pascalize(property.Name!))))),
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("context", "Reply"))
|
|
.AddArgumentListArguments(
|
|
Argument(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("writer", "CreateMessage"))))),
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("writer", "Dispose"))),
|
|
BreakStatement()))))))),
|
|
MethodDeclaration(
|
|
PredefinedType(
|
|
Token(SyntaxKind.VoidKeyword)),
|
|
"ReplyGetAllProperties")
|
|
.AddModifiers(
|
|
Token(SyntaxKind.PublicKeyword))
|
|
.AddParameterListParameters(
|
|
Parameter(
|
|
Identifier("context"))
|
|
.WithType(
|
|
IdentifierName("MethodContext")))
|
|
.WithBody(
|
|
Block(
|
|
ExpressionStatement(
|
|
InvocationExpression(IdentifierName("Reply"))),
|
|
LocalFunctionStatement(PredefinedType(Token(SyntaxKind.VoidKeyword)), Identifier("Reply"))
|
|
.AddBodyStatements(
|
|
LocalDeclarationStatement(
|
|
VariableDeclaration(IdentifierName("MessageWriter"))
|
|
.AddVariables(
|
|
VariableDeclarator("writer")
|
|
.WithInitializer(
|
|
EqualsValueClause(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("context", "CreateReplyWriter"))
|
|
.AddArgumentListArguments(
|
|
Argument(MakeLiteralExpression("a{sv}"))))))),
|
|
LocalDeclarationStatement(
|
|
VariableDeclaration(IdentifierName("ArrayStart"))
|
|
.AddVariables(
|
|
VariableDeclarator("dictStart")
|
|
.WithInitializer(
|
|
EqualsValueClause(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("writer", "WriteDictionaryStart")))))))
|
|
.AddBodyStatements(
|
|
dBusInterface.Properties.SelectMany(property =>
|
|
new StatementSyntax[]
|
|
{
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("writer", "WriteDictionaryEntryStart"))),
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("writer", "WriteString"))
|
|
.AddArgumentListArguments(
|
|
Argument(
|
|
MakeLiteralExpression(property.Name!)))),
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("writer", "WriteSignature"))
|
|
.AddArgumentListArguments(
|
|
Argument(
|
|
MakeLiteralExpression(property.Type!)))),
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("writer", GetOrAddWriteMethod(property)))
|
|
.AddArgumentListArguments(
|
|
Argument(
|
|
IdentifierName(
|
|
Pascalize(property.Name!)))))
|
|
}).ToArray())
|
|
.AddBodyStatements(
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("writer", "WriteDictionaryEnd"))
|
|
.AddArgumentListArguments(
|
|
Argument(
|
|
IdentifierName("dictStart")))),
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("context", "Reply"))
|
|
.AddArgumentListArguments(
|
|
Argument(
|
|
InvocationExpression(MakeMemberAccessExpression("writer", "CreateMessage")))))))));
|
|
}
|
|
|
|
private void AddHandlerIntrospect(ref ClassDeclarationSyntax cl, DBusInterface dBusInterface)
|
|
{
|
|
XmlSerializer xmlSerializer = new(typeof(DBusInterface));
|
|
using StringWriter stringWriter = new();
|
|
using XmlWriter xmlWriter = XmlWriter.Create(stringWriter, new XmlWriterSettings { OmitXmlDeclaration = true, Indent = true });
|
|
xmlSerializer.Serialize(xmlWriter, dBusInterface);
|
|
string introspect = stringWriter.ToString();
|
|
|
|
cl = cl.AddMembers(
|
|
MakeGetOnlyProperty(
|
|
GenericName("ReadOnlyMemory")
|
|
.AddTypeArgumentListArguments(
|
|
PredefinedType(
|
|
Token(SyntaxKind.ByteKeyword))),
|
|
"IntrospectXml",
|
|
Token(SyntaxKind.PublicKeyword))
|
|
.WithInitializer(
|
|
EqualsValueClause(
|
|
InvocationExpression(
|
|
MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, LiteralExpression(SyntaxKind.Utf8StringLiteralExpression, Utf8Literal(introspect)), IdentifierName("ToArray")))))
|
|
.WithSemicolonToken(
|
|
Token(SyntaxKind.SemicolonToken)));
|
|
}
|
|
|
|
private void AddHandlerSignals(ref ClassDeclarationSyntax cl, DBusInterface dBusInterface)
|
|
{
|
|
if (dBusInterface.Signals is null)
|
|
return;
|
|
|
|
foreach (DBusSignal signal in dBusInterface.Signals)
|
|
{
|
|
MethodDeclarationSyntax method = MethodDeclaration(
|
|
PredefinedType(
|
|
Token(SyntaxKind.VoidKeyword)),
|
|
$"Emit{Pascalize(signal.Name!)}")
|
|
.AddModifiers(
|
|
Token(SyntaxKind.ProtectedKeyword));
|
|
|
|
if (signal.Arguments?.Length > 0)
|
|
{
|
|
method = method.WithParameterList(
|
|
ParameterList(
|
|
SeparatedList(
|
|
signal.Arguments.Select(
|
|
static (argument, i) => Parameter(
|
|
Identifier(argument.Name is not null ? SanitizeIdentifier(Camelize(argument.Name)) : $"arg{i}"))
|
|
.WithType(
|
|
GetDotnetType(argument, AccessMode.Write, true))))));
|
|
}
|
|
|
|
BlockSyntax body = Block();
|
|
|
|
body = body.AddStatements(
|
|
LocalDeclarationStatement(
|
|
VariableDeclaration(IdentifierName("MessageWriter"),
|
|
SingletonSeparatedList(
|
|
VariableDeclarator("writer")
|
|
.WithInitializer(EqualsValueClause(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("Connection", "GetMessageWriter"))))))));
|
|
|
|
ArgumentListSyntax args = ArgumentList()
|
|
.AddArguments(
|
|
Argument(
|
|
LiteralExpression(SyntaxKind.NullLiteralExpression)),
|
|
Argument(
|
|
MakeMemberAccessExpression("PathHandler", "Path")),
|
|
Argument(
|
|
MakeLiteralExpression(dBusInterface.Name!)),
|
|
Argument(
|
|
MakeLiteralExpression(signal.Name!)));
|
|
|
|
if (signal.Arguments?.Length > 0)
|
|
{
|
|
args = args.AddArguments(
|
|
Argument(
|
|
MakeLiteralExpression(
|
|
ParseSignature(signal.Arguments)!)));
|
|
}
|
|
|
|
body = body.AddStatements(
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("writer", "WriteSignalHeader"))
|
|
.WithArgumentList(args)));
|
|
|
|
if (signal.Arguments?.Length > 0)
|
|
{
|
|
for (int i = 0; i < signal.Arguments.Length; i++)
|
|
{
|
|
body = body.AddStatements(
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("writer", GetOrAddWriteMethod(signal.Arguments[i])))
|
|
.AddArgumentListArguments(
|
|
Argument(
|
|
IdentifierName(signal.Arguments[i].Name is not null
|
|
? Camelize(signal.Arguments[i].Name!)
|
|
: $"arg{i}")))));
|
|
}
|
|
}
|
|
|
|
body = body.AddStatements(
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("Connection", "TrySendMessage"))
|
|
.AddArgumentListArguments(
|
|
Argument(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("writer", "CreateMessage"))))),
|
|
ExpressionStatement(
|
|
InvocationExpression(
|
|
MakeMemberAccessExpression("writer", "Dispose"))));
|
|
|
|
cl = cl.AddMembers(method.WithBody(body));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|