public MemberDeclarationSyntax MakeInterface(TypeDefinition type)
        {
            var ifaceDecl = InterfaceDeclaration(_names.MakeTypeName(type, NameUsage.Interface).Identifier)
                            .AddModifiers(Public)
                            .AddAttributeLists(
                AttributeList()
                .AddAttributes(
                    CommonSnippetGen.MakeTypeIdAttribute(type.Id),
                    Attribute(IdentifierName("Proxy"))
                    .AddArgumentListArguments(
                        AttributeArgument(
                            TypeOfExpression(_names.MakeGenericTypeNameForAttribute(type, NameUsage.Proxy)))),
                    Attribute(IdentifierName("Skeleton"))
                    .AddArgumentListArguments(
                        AttributeArgument(
                            TypeOfExpression(_names.MakeGenericTypeNameForAttribute(type, NameUsage.Skeleton))))));

            if (type.GenericParameters.Count > 0)
            {
                ifaceDecl = ifaceDecl
                            .AddTypeParameterListParameters(MakeTypeParameters(type).ToArray())
                            .AddConstraintClauses(MakeTypeParameterConstraints(type).ToArray());
            }

            if (type.Superclasses.Count == 0)
            {
                ifaceDecl = ifaceDecl.AddBaseListTypes(SimpleBaseType(IdentifierName(nameof(IDisposable))));
            }
            else
            {
                foreach (var superClass in type.Superclasses)
                {
                    ifaceDecl = ifaceDecl.AddBaseListTypes(
                        SimpleBaseType(_names.MakeTypeSyntax(
                                           superClass, type,
                                           TypeUsage.DomainClass,
                                           Nullability.NonNullable)));
                }
            }

            foreach (var method in type.Methods)
            {
                var methodDecl = MethodDeclaration(
                    TransformReturnType(method),
                    _names.GetCodeIdentifier(method).Identifier)
                                 .AddParameterListParameters(TransformParameters(method))
                                 .WithSemicolonToken(Token(SyntaxKind.SemicolonToken));

                if (method.GenericParameters.Count > 0)
                {
                    methodDecl = methodDecl
                                 .AddTypeParameterListParameters(MakeTypeParameters(method).ToArray())
                                 .AddConstraintClauses(MakeTypeParameterConstraints(method).ToArray());
                }

                ifaceDecl = ifaceDecl.AddMembers(methodDecl);
            }

            return(ifaceDecl);
        }
 public CodeGenerator(SchemaModel model, GeneratorOptions options)
 {
     _model        = model;
     _names        = new GenNames(options);
     _commonGen    = new CommonSnippetGen(_names);
     _domClassGen  = new DomainClassSnippetGen(_names);
     _readerGen    = new ReaderSnippetGen(_names);
     _writerGen    = new WriterSnippetGen(_names);
     _interfaceGen = new InterfaceSnippetGen(_names);
 }
        IEnumerable <MemberDeclarationSyntax> TransformStruct(TypeDefinition def)
        {
            var topDecl = ClassDeclaration(_names.MakeTypeName(def).Identifier)
                          .AddModifiers(Public)
                          .AddBaseListTypes(SimpleBaseType(Type <Capnp.ICapnpSerializable>()));

            if (def.GenericParameters.Count > 0)
            {
                topDecl = topDecl
                          .AddTypeParameterListParameters(MakeTypeParameters(def).ToArray())
                          .AddConstraintClauses(MakeTypeParameterConstraints(def).ToArray());
            }

            topDecl = topDecl.AddMembers(CommonSnippetGen.MakeTypeIdConst(def.Id, _names));
            topDecl = topDecl.WithAttributeLists(CommonSnippetGen.MakeTypeIdAttributeLists(def.Id));

            if (def.UnionInfo != null)
            {
                topDecl = topDecl.AddMembers(_commonGen.MakeUnionSelectorEnum(def));
            }

            topDecl = topDecl.AddMembers(_domClassGen.MakeDomainClassMembers(def));
            topDecl = topDecl.AddMembers(_readerGen.MakeReaderStruct(def));
            topDecl = topDecl.AddMembers(_writerGen.MakeWriterStruct(def));

            foreach (var nestedGroup in def.NestedGroups)
            {
                topDecl = topDecl.AddMembers(Transform(nestedGroup).ToArray());
            }

            foreach (var nestedDef in def.NestedTypes)
            {
                topDecl = topDecl.AddMembers(Transform(nestedDef).ToArray());
            }

            yield return(topDecl);
        }
Exemple #4
0
        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);
        }
 public static SyntaxList <AttributeListSyntax> MakeTypeIdAttributeLists(ulong id) =>
 SingletonList <AttributeListSyntax>(
     AttributeList(
         SingletonSeparatedList <AttributeSyntax>(
             CommonSnippetGen.MakeTypeIdAttribute(id))));