public MemberDeclarationSyntax MakeProxy(TypeDefinition type) { var classDecl = ClassDeclaration(_names.MakeTypeName(type, NameUsage.Proxy).Identifier) .AddAttributeLists(_names.MakeTypeDecorationAttributes(type.Id)) .AddModifiers(Public) .AddBaseListTypes( SimpleBaseType(_names.Type <Capnp.Rpc.Proxy>(Nullability.NonNullable)), SimpleBaseType(_names.MakeGenericTypeName(type, NameUsage.Interface))); if (type.GenericParameters.Count > 0) { classDecl = classDecl .AddTypeParameterListParameters(MakeTypeParameters(type).ToArray()) .AddConstraintClauses(MakeTypeParameterConstraints(type).ToArray()); } var allMethods = from c in Types.FromDefinition(type).AllImplementedClasses from m in c.Methods select m; foreach (var method in allMethods) { var bodyStmts = new List <StatementSyntax>(); bodyStmts.Add(LocalDeclarationStatement( VariableDeclaration( IdentifierName("var")) .WithVariables( SingletonSeparatedList( VariableDeclarator( _names.ParamsLocal.Identifier) .WithInitializer( EqualsValueClause( InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, IdentifierName(nameof(Capnp.SerializerState)), GenericName( Identifier(nameof(Capnp.SerializerState.CreateForRpc))) .WithTypeArgumentList( TypeArgumentList( SingletonSeparatedList( _names.MakeTypeSyntax( method.ParamsStruct, method.ParamsStruct.Definition, TypeUsage.Writer, Nullability.NonNullable)))))))))))); if (method.ParamsStruct.Definition.SpecialName == SpecialName.MethodParamsStruct) { bodyStmts.Add(LocalDeclarationStatement( VariableDeclaration( IdentifierName("var")) .WithVariables( SingletonSeparatedList <VariableDeclaratorSyntax>( VariableDeclarator( _names.AnonymousParameter.Identifier) .WithInitializer( EqualsValueClause( ObjectCreationExpression( _names.MakeTypeSyntax( method.ParamsStruct, method.ParamsStruct.Definition, TypeUsage.DomainClass, Nullability.NonNullable)) .WithArgumentList( ArgumentList()) .WithInitializer( InitializerExpression( SyntaxKind.ObjectInitializerExpression, SeparatedList <ExpressionSyntax>( CommonSnippetGen.MakeCommaSeparatedList( MakeProxyCallInitializerAssignments(method)).ToArray()))))))))); } bodyStmts.Add(ExpressionStatement( ConditionalAccessExpression( _names.AnonymousParameter.IdentifierName, InvocationExpression( MemberBindingExpression(_names.SerializeMethod.IdentifierName)) .AddArgumentListArguments( Argument(_names.ParamsLocal.IdentifierName))))); var call = InvocationExpression(IdentifierName(nameof(Capnp.Rpc.BareProxy.Call))) .AddArgumentListArguments( Argument( LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(method.DeclaringInterface.Id))), Argument( LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(method.Id))), Argument( InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, _names.ParamsLocal.IdentifierName, GenericName(nameof(Capnp.SerializerState.Rewrap)) .AddTypeArgumentListArguments(_names.Type <Capnp.DynamicSerializerState>(Nullability.NonNullable)))) .AddArgumentListArguments()), Argument( LiteralExpression(SyntaxKind.FalseLiteralExpression)), Argument( _names.CancellationTokenParameter.IdentifierName)); MethodDeclarationSyntax methodDecl; if (IsSubjectToPipelining(method)) { methodDecl = MethodDeclaration( TransformReturnType(method), _names.GetCodeIdentifier(method).Identifier) .AddParameterListParameters(TransformParameters(method)) .AddModifiers(Public); var pipelineAwareCall = InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, IdentifierName(nameof(Capnp.Rpc.Impatient)), IdentifierName(nameof(Capnp.Rpc.Impatient.MakePipelineAware)))) .AddArgumentListArguments( Argument(call), Argument(SimpleLambdaExpression( Parameter(_names.DeserializerLocal.Identifier), Block( UsingStatement( Block( MakeProxyCreateResult(method), MakeProxyReturnResult(method))) .WithExpression(_names.DeserializerLocal.IdentifierName))))); bodyStmts.Add(ReturnStatement(pipelineAwareCall)); } else { methodDecl = MethodDeclaration( TransformReturnType(method), _names.GetCodeIdentifier(method).Identifier) .AddParameterListParameters(TransformParameters(method)) .AddModifiers(Public, Token(SyntaxKind.AsyncKeyword)); var whenReturned = MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, call, IdentifierName(nameof(Capnp.Rpc.IPromisedAnswer.WhenReturned))); bodyStmts.Add(UsingStatement( Block( MakeProxyCreateResult(method), MakeProxyReturnResult(method))) .WithDeclaration(VariableDeclaration( IdentifierName("var")) .AddVariables( VariableDeclarator( _names.DeserializerLocal.Identifier) .WithInitializer( EqualsValueClause( AwaitExpression(whenReturned)))))); } if (method.GenericParameters.Count > 0) { methodDecl = methodDecl .AddTypeParameterListParameters(MakeTypeParameters(method).ToArray()) .AddConstraintClauses(MakeTypeParameterConstraints(method).ToArray()); } methodDecl = methodDecl.AddBodyStatements(bodyStmts.ToArray()); classDecl = classDecl.AddMembers(methodDecl); } return(classDecl); }