コード例 #1
0
        private MethodCallBuilder CreateBuildDataStatement(ObjectTypeDescriptor concreteType)
        {
            MethodCallBuilder returnStatement = MethodCallBuilder
                                                .New()
                                                .SetNew()
                                                .SetMethodName(
                $"{concreteType.RuntimeType.Namespace}.State." +
                CreateDataTypeName(concreteType.Name))
                                                .AddArgument("typename");

            foreach (PropertyDescriptor property in concreteType.Properties)
            {
                if (property.Name.Value.EqualsOrdinal(WellKnownNames.TypeName))
                {
                    continue;
                }

                returnStatement.AddArgument(
                    CodeBlockBuilder
                    .New()
                    .AddCode($"{GetParameterName(property.Name)}: ")
                    .AddCode(BuildUpdateMethodCall(property)));
            }

            return(returnStatement);
        }
コード例 #2
0
        protected CodeLinePragma CreateCodeLinePragma(ControlBuilder builder)
        {
            string virtualPath     = builder.PageVirtualPath;
            int    line            = builder.Line;
            int    column          = 1;
            int    generatedColumn = 1;
            int    codeLength      = -1;

            CodeBlockBuilder codeBlockBuilder = builder as CodeBlockBuilder;

            if (codeBlockBuilder != null)
            {
                column     = codeBlockBuilder.Column;
                codeLength = codeBlockBuilder.Content.Length;

                if (codeBlockBuilder.BlockType == CodeBlockType.Code)
                {
                    // If it's a <% ... %> block, the generated column is the same as the source
                    generatedColumn = column;
                }
                else
                {
                    // If it's a <%= ... %> block, we always generate '__o = expr' is
                    // designer mode, so the column is fixed
                    //
                    generatedColumn = BaseTemplateCodeDomTreeGenerator.tempObjectVariable.Length +
                                      GetGeneratedColumnOffset(_codeDomProvider);
                }
            }

            return(CreateCodeLinePragma(virtualPath, line, column, generatedColumn, codeLength));
        }
コード例 #3
0
 private static ICode GenerateMethodBody(
     CSharpSyntaxGeneratorSettings settings,
     DependencyInjectionDescriptor descriptor) =>
 CodeBlockBuilder
 .New()
 .AddMethodCall(x => x
                .SetMethodName(TypeNames.AddSingleton)
                .AddArgument(_services)
                .AddArgument(LambdaBuilder
                             .New()
                             .SetBlock(true)
                             .AddArgument(_sp)
                             .SetCode(GenerateClientServiceProviderFactory(descriptor))))
 .AddEmptyLine()
 .AddCode(RegisterStoreAccessor(settings, descriptor.StoreAccessor))
 .AddEmptyLine()
 .ForEach(
     descriptor.Operations,
     (builder, operation) =>
     builder.AddCode(ForwardSingletonToClientServiceProvider(
                         operation.RuntimeType.ToString())))
 .AddEmptyLine()
 .AddCode(ForwardSingletonToClientServiceProvider(
              descriptor.ClientDescriptor.RuntimeType.ToString()))
 .AddCode(ForwardSingletonToClientServiceProvider(
              descriptor.ClientDescriptor.InterfaceType.ToString()))
 .AddEmptyLine()
 .AddMethodCall(x => x
                .SetReturn()
                .SetNew()
                .SetMethodName(
                    TypeNames.ClientBuilder.WithGeneric(descriptor.StoreAccessor.RuntimeType))
                .AddArgument(descriptor.Name.AsStringToken())
                .AddArgument(_services));
コード例 #4
0
        private static void EmitInvokeCommand(CodeBlockBuilder tryBlock, TypeSet.VkHandleMethod method, Func <IEnumerable <Action <ExpressionBuilder> >, Action <ExpressionBuilder> > commandExpression, Func <TypeSet.VkMethodParam, string> argumentNameSelector, string commandResultVariable)
        {
            foreach (var fixedArgument in method.Parameters.Where(x => !string.IsNullOrEmpty(x.FixedName)))
            {
                tryBlock.EmitStatement($"fixed({fixedArgument.FixedType} {fixedArgument.FixedName} = {fixedArgument.Name})");
            }

            var arguments = method.Parameters.Select(argumentNameSelector).Select(Variable);

            if (method.IsPassthroughResult)
            {
                tryBlock.EmitAssignment(Variable("result"), commandExpression(arguments));
            }
            else if (method.HasVkResult)
            {
                tryBlock.EmitAssignment(Variable(commandResultVariable), commandExpression(arguments));
            }
            else
            {
                tryBlock.EmitCallExpression(commandExpression(arguments));
            }

            if (method.HasVkResult)
            {
                tryBlock.EmitIfBlock(StaticCall("SharpVkException", "IsError", Variable(commandResultVariable)), ifBlock =>
                {
                    ifBlock.EmitThrow(StaticCall("SharpVkException", "Create", Variable(commandResultVariable)));
                });
            }
        }
コード例 #5
0
 private static ICode RegisterHttpConnection(string clientName) =>
 MethodCallBuilder
 .New()
 .SetMethodName(TypeNames.AddSingleton)
 .AddArgument(_services)
 .AddGeneric(TypeNames.IHttpConnection)
 .AddArgument(LambdaBuilder
              .New()
              .AddArgument(_sp)
              .SetBlock(true)
              .SetCode(CodeBlockBuilder
                       .New()
                       .AddCode(AssignmentBuilder
                                .New()
                                .SetLefthandSide($"var {_clientFactory}")
                                .SetRighthandSide(MethodCallBuilder
                                                  .Inline()
                                                  .SetMethodName(TypeNames.GetRequiredService)
                                                  .AddGeneric(TypeNames.IHttpClientFactory)
                                                  .AddArgument(_parentServices)))
                       .AddCode(MethodCallBuilder
                                .New()
                                .SetReturn()
                                .SetNew()
                                .SetMethodName(TypeNames.HttpConnection)
                                .AddArgument(LambdaBuilder
                                             .New()
                                             .SetCode(MethodCallBuilder
                                                      .Inline()
                                                      .SetMethodName(
                                                          _clientFactory,
                                                          nameof(IHttpClientFactory.CreateClient))
                                                      .AddArgument(clientName.AsStringToken()))))));
コード例 #6
0
        private IfBuilder GenerateComplexDataInterfaceIfClause(
            ObjectTypeDescriptor objectTypeDescriptor,
            string variableName)
        {
            var matchedTypeName = GetParameterName(objectTypeDescriptor.Name);

            // since we want to create the data name we will need to craft the type name
            // by hand by using the GraphQL type name and the state namespace.
            var dataTypeName = new RuntimeTypeInfo(
                CreateDataTypeName(objectTypeDescriptor.Name),
                $"{objectTypeDescriptor.RuntimeType.Namespace}.State");

            var block = CodeBlockBuilder.New();

            MethodCallBuilder constructorCall = MethodCallBuilder
                                                .Inline()
                                                .SetNew()
                                                .SetMethodName(objectTypeDescriptor.RuntimeType.ToString());

            foreach (PropertyDescriptor prop in objectTypeDescriptor.Properties)
            {
                if (prop.Type.IsEntityType())
                {
                    constructorCall.AddArgument(BuildMapMethodCall(matchedTypeName, prop));
                }
                else if (prop.Type.IsNonNullableType())
                {
                    if (prop.Type.NamedType() is ILeafTypeDescriptor
                    {
                        RuntimeType: { IsValueType: true }
                    })
コード例 #7
0
ファイル: MethodBuilder.cs プロジェクト: MichalTecl/Robowire
 public MethodBuilder(string name, int indent)
     : base(name)
 {
     m_indent = indent;
     m_body   = new CodeBlockBuilder(m_indent + 1);
     ReturnsVoid();
 }
        private void AddInterfaceDataTypeDeserializerToMethod(
            MethodBuilder methodBuilder,
            InterfaceTypeDescriptor interfaceTypeDescriptor)
        {
            methodBuilder.AddCode(
                AssignmentBuilder
                .New()
                .SetLefthandSide($"var {_typename}")
                .SetRighthandSide(MethodCallBuilder
                                  .Inline()
                                  .SetMethodName(
                                      _obj,
                                      "Value",
                                      nameof(JsonElement.GetProperty))
                                  .AddArgument(WellKnownNames.TypeName.AsStringToken())
                                  .Chain(x => x.SetMethodName(nameof(JsonElement.GetString)))));

            // If the type is an interface
            foreach (ObjectTypeDescriptor concreteType in interfaceTypeDescriptor.ImplementedBy)
            {
                MethodCallBuilder returnStatement = MethodCallBuilder
                                                    .New()
                                                    .SetReturn()
                                                    .SetNew()
                                                    .SetMethodName(
                    $"{concreteType.RuntimeType.Namespace}.State." +
                    CreateDataTypeName(concreteType.Name))
                                                    .AddArgument("typename");

                foreach (PropertyDescriptor property in concreteType.Properties)
                {
                    if (property.Name.Value.EqualsOrdinal(WellKnownNames.TypeName))
                    {
                        continue;
                    }

                    returnStatement.AddArgument(
                        CodeBlockBuilder
                        .New()
                        .AddCode($"{GetParameterName(property.Name)}: ")
                        .AddCode(BuildUpdateMethodCall(property)));
                }

                IfBuilder ifStatement = IfBuilder
                                        .New()
                                        .SetCondition(
                    $"typename?.Equals(\"{concreteType.Name}\", " +
                    $"{TypeNames.OrdinalStringComparison}) ?? false")
                                        .AddCode(returnStatement);

                methodBuilder
                .AddEmptyLine()
                .AddCode(ifStatement);
            }

            methodBuilder
            .AddEmptyLine()
            .AddCode(ExceptionBuilder.New(TypeNames.NotSupportedException));
        }
コード例 #9
0
        protected override void Generate(
            InputObjectTypeDescriptor descriptor,
            CSharpSyntaxGeneratorSettings settings,
            CodeWriter writer,
            out string fileName,
            out string?path,
            out string ns)
        {
            const string serializerResolver = nameof(serializerResolver);
            const string runtimeValue       = nameof(runtimeValue);
            const string input     = nameof(input);
            const string inputInfo = nameof(inputInfo);
            const string fields    = nameof(fields);

            fileName = CreateInputValueFormatter(descriptor);
            path     = Serialization;
            ns       = descriptor.RuntimeType.NamespaceWithoutGlobal;

            string stateNamespace    = $"{descriptor.RuntimeType.Namespace}.{State}";
            string infoInterfaceType = $"{stateNamespace}.{CreateInputValueInfo(descriptor.Name)}";

            ClassBuilder classBuilder = ClassBuilder
                                        .New()
                                        .SetName(fileName)
                                        .AddImplements(TypeNames.IInputObjectFormatter);

            var neededSerializers = descriptor
                                    .Properties
                                    .GroupBy(x => x.Type.Name)
                                    .ToDictionary(x => x, x => x.First());

            //  Initialize Method

            CodeBlockBuilder initialize = classBuilder
                                          .AddMethod("Initialize")
                                          .SetPublic()
                                          .AddParameter(serializerResolver, x => x.SetType(TypeNames.ISerializerResolver))
                                          .AddBody();

            foreach (var property in neededSerializers.Values)
            {
                if (property.Type.GetName().Value is { } name)
                {
                    var propertyName = GetFieldName(name) + "Formatter";

                    initialize
                    .AddAssigment(propertyName)
                    .AddMethodCall()
                    .SetMethodName(serializerResolver, "GetInputValueFormatter")
                    .AddArgument(name.AsStringToken());

                    classBuilder
                    .AddField(propertyName)
                    .SetAccessModifier(AccessModifier.Private)
                    .SetType(TypeNames.IInputValueFormatter)
                    .SetValue("default!");
                }
コード例 #10
0
        protected override void Generate(
            CodeWriter writer,
            InputObjectTypeDescriptor namedTypeDescriptor,
            out string fileName,
            out string?path)
        {
            const string serializerResolver = nameof(serializerResolver);
            const string runtimeValue       = nameof(runtimeValue);
            const string value = nameof(value);

            fileName = CreateInputValueFormatter(namedTypeDescriptor);
            path     = Serialization;

            NameString typeName = namedTypeDescriptor.Name;

            ClassBuilder classBuilder = ClassBuilder
                                        .New()
                                        .SetName(fileName)
                                        .AddImplements(TypeNames.IInputObjectFormatter);

            var neededSerializers = namedTypeDescriptor
                                    .Properties
                                    .GroupBy(x => x.Type.Name)
                                    .ToDictionary(x => x, x => x.First());

            //  Initialize Method

            CodeBlockBuilder initialize = classBuilder
                                          .AddMethod("Initialize")
                                          .SetPublic()
                                          .AddParameter(serializerResolver, x => x.SetType(TypeNames.ISerializerResolver))
                                          .AddBody();

            foreach (var property in neededSerializers.Values)
            {
                if (property.Type.GetName().Value is { } name)
                {
                    var propertyName = GetFieldName(name) + "Formatter";

                    initialize
                    .AddAssigment(propertyName)
                    .AddMethodCall()
                    .SetMethodName(
                        serializerResolver,
                        "GetInputValueFormatter")
                    .AddArgument(name.AsStringToken());

                    classBuilder
                    .AddField(propertyName)
                    .SetAccessModifier(AccessModifier.Private)
                    .SetType(TypeNames.IInputValueFormatter)
                    .SetValue("default!");
                }
コード例 #11
0
ファイル: MethodEmitter.cs プロジェクト: yaram/SharpVk
        public static void EmitMarshalAction(CodeBlockBuilder codeBlock, Generation.AssignAction action, Action <ExpressionBuilder> targetExpression)
        {
            switch (action.Type)
            {
            case AssignActionType.Assign:
                codeBlock.EmitAssignment(targetExpression, action.ValueExpression);
                break;

            case AssignActionType.Alloc:
                if (action.LengthExpression != null)
                {
                    codeBlock.EmitAssignment(targetExpression,
                                             Cast(action.MemberType + "*", StaticCall("Interop.HeapUtil", $"Allocate<{action.MemberType}>", action.LengthExpression)));
                }
                else
                {
                    codeBlock.EmitAssignment(targetExpression,
                                             Cast(action.MemberType + "*", StaticCall("Interop.HeapUtil", $"Allocate<{action.MemberType}>")));
                }
                break;

            case AssignActionType.AllocAndAssign:
                codeBlock.EmitAssignment(targetExpression,
                                         Cast(action.MemberType + "*", StaticCall("Interop.HeapUtil", $"Allocate<{action.MemberType}>")));
                codeBlock.EmitAssignment(Deref(targetExpression), action.ValueExpression);
                break;

            case AssignActionType.MarshalToAddressOf:
                codeBlock.EmitCall(action.ValueExpression, "MarshalTo", AddressOf(targetExpression));
                break;

            case AssignActionType.MarshalTo:
                codeBlock.EmitAssignment(targetExpression,
                                         Cast(action.MemberType + "*", StaticCall("Interop.HeapUtil", $"Allocate<{action.MemberType}>")));
                codeBlock.EmitCall(action.ValueExpression, "MarshalTo", targetExpression);
                break;

            case AssignActionType.MarshalFrom:
                codeBlock.EmitAssignment(targetExpression,
                                         StaticCall(action.MemberType, "MarshalFrom", action.ValueExpression));
                break;

            case AssignActionType.MarshalFromAddressOf:
                codeBlock.EmitAssignment(targetExpression,
                                         StaticCall(action.MemberType, "MarshalFrom", AddressOf(action.ValueExpression)));
                break;

            case AssignActionType.FixedLengthMarshalTo:
                codeBlock.EmitStaticCall("Interop.HeapUtil", "MarshalTo", action.ValueExpression, action.LengthExpression, targetExpression);
                break;
            }
        }
コード例 #12
0
        private void AddArrayHandler(
            ClassBuilder classBuilder,
            MethodBuilder methodBuilder,
            ListTypeDescriptor listTypeDescriptor,
            HashSet <string> processed)
        {
            var listVarName = GetParameterName(listTypeDescriptor.Name) + "s";

            methodBuilder
            .AddCode(
                AssignmentBuilder
                .New()
                .SetLefthandSide($"var {listVarName}")
                .SetRighthandSide(
                    CodeBlockBuilder
                    .New()
                    .AddCode("new ")
                    .AddCode(TypeNames.List)
                    .AddCode("<")
                    .AddCode(
                        listTypeDescriptor.InnerType
                        .ToStateTypeReference()
                        .SkipTrailingSpace())
                    .AddCode(">")
                    .AddCode("()")))
            .AddEmptyLine()
            .AddCode(
                ForEachBuilder
                .New()
                .SetLoopHeader(
                    $"{TypeNames.JsonElement} {_child} in {_obj}.Value.EnumerateArray()")
                .AddCode(
                    MethodCallBuilder
                    .New()
                    .SetMethodName(listVarName, nameof(List <object> .Add))
                    .AddArgument(
                        BuildUpdateMethodCall(
                            listTypeDescriptor.InnerType,
                            CodeInlineBuilder.From(_child)))))
            .AddEmptyLine()
            .AddCode($"return {listVarName};");

            AddDeserializeMethod(listTypeDescriptor.InnerType, classBuilder, processed);
        }
コード例 #13
0
        private ICode ParseEntityIdBody(EntityIdFactoryDescriptor descriptor)
        {
            AssignmentBuilder typeNameAssignment =
                AssignmentBuilder
                .New()
                .SetLefthandSide($"{TypeNames.String} {WellKnownNames.TypeName}")
                .SetRighthandSide(
                    MethodCallBuilder
                    .Inline()
                    .SetMethodName(_obj, nameof(JsonElement.GetProperty))
                    .AddArgument(WellKnownNames.TypeName.AsStringToken())
                    .Chain(x => x
                           .SetMethodName(nameof(JsonElement.GetString))
                           .SetNullForgiving()));

            SwitchExpressionBuilder typeNameSwitch =
                SwitchExpressionBuilder
                .New()
                .SetReturn()
                .SetExpression(WellKnownNames.TypeName)
                .SetDefaultCase(ExceptionBuilder.Inline(TypeNames.NotSupportedException));

            foreach (var entity in descriptor.Entities)
            {
                typeNameSwitch.AddCase(
                    entity.Name.AsStringToken(),
                    MethodCallBuilder
                    .Inline()
                    .SetMethodName($"Parse{entity.Name}EntityId")
                    .AddArgument(_obj)
                    .AddArgument(WellKnownNames.TypeName));
            }

            return(CodeBlockBuilder
                   .New()
                   .AddCode(typeNameAssignment)
                   .AddEmptyLine()
                   .AddCode(typeNameSwitch));
        }
コード例 #14
0
        private ICode FormatEntityIdBody(EntityIdFactoryDescriptor descriptor)
        {
            SwitchExpressionBuilder typeNameSwitch =
                SwitchExpressionBuilder
                .New()
                .SetReturn()
                .SetExpression($"{_entityId}.Name")
                .SetDefaultCase(ExceptionBuilder.Inline(TypeNames.NotSupportedException));

            foreach (var entity in descriptor.Entities)
            {
                typeNameSwitch.AddCase(
                    entity.Name.AsStringToken(),
                    MethodCallBuilder
                    .Inline()
                    .SetMethodName($"Format{entity.Name}EntityId")
                    .AddArgument(_entityId));
            }

            return(CodeBlockBuilder
                   .New()
                   .AddCode(typeNameSwitch));
        }
コード例 #15
0
        protected CodeLinePragma CreateCodeLinePragma(ControlBuilder builder)
        {
            string           pageVirtualPath = builder.PageVirtualPath;
            int              line            = builder.Line;
            int              column          = 1;
            int              generatedColumn = 1;
            int              codeLength      = -1;
            CodeBlockBuilder builder2        = builder as CodeBlockBuilder;

            if (builder2 != null)
            {
                column     = builder2.Column;
                codeLength = builder2.Content.Length;
                if (builder2.BlockType == CodeBlockType.Code)
                {
                    generatedColumn = column;
                }
                else
                {
                    generatedColumn = "__o".Length + GetGeneratedColumnOffset(this._codeDomProvider);
                }
            }
            return(this.CreateCodeLinePragma(pageVirtualPath, line, column, generatedColumn, codeLength));
        }
コード例 #16
0
        private static ICode GenerateClientServiceProviderFactory(
            DependencyInjectionDescriptor descriptor)
        {
            if (descriptor.TransportProfiles.Count == 1)
            {
                return(CodeBlockBuilder
                       .New()
                       .AddCode(
                           AssignmentBuilder
                           .New()
                           .SetLefthandSide($"var {_serviceCollection}")
                           .SetRighthandSide(
                               MethodCallBuilder
                               .Inline()
                               .SetMethodName(
                                   "ConfigureClient" +
                                   descriptor.TransportProfiles[0].Name)
                               .AddArgument(_sp)
                               .AddArgument(_strategy)))
                       .AddEmptyLine()
                       .AddCode(MethodCallBuilder
                                .New()
                                .SetReturn()
                                .SetNew()
                                .SetMethodName("ClientServiceProvider")
                                .SetWrapArguments()
                                .AddArgument(MethodCallBuilder
                                             .Inline()
                                             .SetMethodName(TypeNames.BuildServiceProvider)
                                             .AddArgument(_serviceCollection))));
            }

            SwitchExpressionBuilder switchBuilder = SwitchExpressionBuilder
                                                    .New()
                                                    .SetExpression(_profile)
                                                    .SetDetermineStatement(false)
                                                    .SetDefaultCase(ExceptionBuilder.Inline(TypeNames.ArgumentOutOfRangeException));

            var enumName = CreateProfileEnumReference(descriptor);

            foreach (var profile in descriptor.TransportProfiles)
            {
                switchBuilder
                .AddCase(
                    $"{enumName}.{profile.Name}",
                    MethodCallBuilder
                    .Inline()
                    .SetMethodName("ConfigureClient" + profile.Name)
                    .AddArgument(_sp)
                    .AddArgument(_strategy));
            }

            return(CodeBlockBuilder
                   .New()
                   .AddCode(
                       AssignmentBuilder
                       .New()
                       .SetLefthandSide($"var {_serviceCollection}")
                       .SetRighthandSide(switchBuilder))
                   .AddEmptyLine()
                   .AddCode(MethodCallBuilder
                            .New()
                            .SetReturn()
                            .SetNew()
                            .SetMethodName("ClientServiceProvider")
                            .SetWrapArguments()
                            .AddArgument(MethodCallBuilder
                                         .Inline()
                                         .SetMethodName(TypeNames.BuildServiceProvider)
                                         .AddArgument(_serviceCollection))));
        }
コード例 #17
0
 private static ICode RegisterOperation(
     CSharpSyntaxGeneratorSettings settings,
     string connectionKind,
     string operationFullName,
     string operationInterfaceName,
     string resultInterface,
     string factory,
     string resultBuilder)
 {
     return(CodeBlockBuilder
            .New()
            .AddCode(
                MethodCallBuilder
                .New()
                .SetMethodName(TypeNames.AddSingleton)
                .AddGeneric(
                    TypeNames.IOperationResultDataFactory.WithGeneric(resultInterface))
                .AddGeneric(factory)
                .AddArgument(_services))
            .AddCode(
                MethodCallBuilder
                .New()
                .SetMethodName(TypeNames.AddSingleton)
                .AddGeneric(TypeNames.IOperationResultDataFactory)
                .AddArgument(_services)
                .AddArgument(LambdaBuilder
                             .New()
                             .AddArgument(_sp)
                             .SetCode(MethodCallBuilder
                                      .Inline()
                                      .SetMethodName(TypeNames.GetRequiredService)
                                      .AddGeneric(
                                          TypeNames.IOperationResultDataFactory
                                          .WithGeneric(resultInterface))
                                      .AddArgument(_sp))))
            .AddCode(
                MethodCallBuilder
                .New()
                .SetMethodName(TypeNames.AddSingleton)
                .AddGeneric(TypeNames.IOperationRequestFactory)
                .AddArgument(_services)
                .AddArgument(LambdaBuilder
                             .New()
                             .AddArgument(_sp)
                             .SetCode(MethodCallBuilder
                                      .Inline()
                                      .SetMethodName(TypeNames.GetRequiredService)
                                      .AddGeneric(operationInterfaceName)
                                      .AddArgument(_sp))))
            .AddCode(MethodCallBuilder
                     .New()
                     .SetMethodName(TypeNames.AddSingleton)
                     .AddGeneric(
                         TypeNames.IOperationResultBuilder
                         .WithGeneric(TypeNames.JsonDocument, resultInterface))
                     .AddGeneric(resultBuilder)
                     .AddArgument(_services))
            .AddCode(
                MethodCallBuilder
                .New()
                .SetMethodName(TypeNames.AddSingleton)
                .AddGeneric(TypeNames.IOperationExecutor.WithGeneric(resultInterface))
                .AddArgument(_services)
                .AddArgument(LambdaBuilder
                             .New()
                             .AddArgument(_sp)
                             .SetCode(MethodCallBuilder
                                      .Inline()
                                      .SetNew()
                                      .SetMethodName(settings.IsStoreEnabled()
                             ? TypeNames.OperationExecutor
                             : TypeNames.StorelessOperationExecutor)
                                      .AddGeneric(TypeNames.JsonDocument)
                                      .AddGeneric(resultInterface)
                                      .AddArgument(
                                          MethodCallBuilder
                                          .Inline()
                                          .SetMethodName(TypeNames.GetRequiredService)
                                          .AddGeneric(connectionKind)
                                          .AddArgument(_sp))
                                      .AddArgument(
                                          LambdaBuilder
                                          .New()
                                          .SetCode(
                                              MethodCallBuilder
                                              .Inline()
                                              .SetMethodName(
                                                  TypeNames.GetRequiredService)
                                              .AddGeneric(
                                                  TypeNames.IOperationResultBuilder.WithGeneric(
                                                      TypeNames.JsonDocument,
                                                      resultInterface))
                                              .AddArgument(_sp)))
                                      .If(settings.IsStoreEnabled(),
                                          x => x
                                          .AddArgument(
                                              MethodCallBuilder
                                              .Inline()
                                              .SetMethodName(TypeNames.GetRequiredService)
                                              .AddGeneric(TypeNames.IOperationStore)
                                              .AddArgument(_sp))
                                          .AddArgument(_strategy)))))
            .AddCode(MethodCallBuilder
                     .New()
                     .SetMethodName(TypeNames.AddSingleton)
                     .AddGeneric(operationFullName)
                     .AddArgument(_services))
            .AddCode(MethodCallBuilder
                     .New()
                     .SetMethodName(TypeNames.AddSingleton)
                     .AddGeneric(operationInterfaceName)
                     .AddArgument(_services)
                     .AddArgument(LambdaBuilder
                                  .New()
                                  .AddArgument(_sp)
                                  .SetCode(MethodCallBuilder
                                           .Inline()
                                           .SetMethodName(TypeNames.GetRequiredService)
                                           .AddGeneric(operationFullName)
                                           .AddArgument(_sp)))));
 }
コード例 #18
0
        private static ICode GenerateInternalMethodBody(
            CSharpSyntaxGeneratorSettings settings,
            DependencyInjectionDescriptor descriptor,
            TransportProfile profile)
        {
            var rootNamespace = descriptor.ClientDescriptor.RuntimeType.Namespace;

            var hasSubscriptions =
                descriptor.Operations.OfType <SubscriptionOperationDescriptor>().Any();
            var hasQueries =
                descriptor.Operations.OfType <QueryOperationDescriptor>().Any();
            var hasMutations =
                descriptor.Operations.OfType <MutationOperationDescriptor>().Any();

            CodeBlockBuilder body = CodeBlockBuilder
                                    .New()
                                    .AddCode(CreateBaseCode(settings));

            var generatedConnections = new HashSet <TransportType>();

            if (hasSubscriptions)
            {
                generatedConnections.Add(profile.Subscription);
                body.AddCode(
                    RegisterConnection(profile.Subscription, descriptor.Name));
            }

            if (hasQueries && !generatedConnections.Contains(profile.Query))
            {
                generatedConnections.Add(profile.Query);
                body.AddCode(RegisterConnection(profile.Query, descriptor.Name));
            }

            if (hasMutations && !generatedConnections.Contains(profile.Mutation))
            {
                generatedConnections.Add(profile.Mutation);
                body.AddCode(RegisterConnection(profile.Mutation, descriptor.Name));
            }

            body.AddEmptyLine();

            foreach (var typeDescriptor in descriptor.TypeDescriptors
                     .OfType <INamedTypeDescriptor>())
            {
                if (typeDescriptor.Kind == TypeKind.Entity && !typeDescriptor.IsInterface())
                {
                    INamedTypeDescriptor namedTypeDescriptor =
                        (INamedTypeDescriptor)typeDescriptor.NamedType();
                    NameString className = namedTypeDescriptor.ExtractMapperName();

                    var interfaceName =
                        TypeNames.IEntityMapper.WithGeneric(
                            namedTypeDescriptor.ExtractType().ToString(),
                            $"{rootNamespace}.{typeDescriptor.RuntimeType.Name}");

                    body.AddMethodCall()
                    .SetMethodName(TypeNames.AddSingleton)
                    .AddGeneric(interfaceName)
                    .AddGeneric($"{CreateStateNamespace(rootNamespace)}.{className}")
                    .AddArgument(_services);
                }
            }

            body.AddEmptyLine();

            foreach (var enumType in descriptor.EnumTypeDescriptor)
            {
                body.AddMethodCall()
                .SetMethodName(TypeNames.AddSingleton)
                .AddGeneric(TypeNames.ISerializer)
                .AddGeneric(CreateEnumParserName($"{rootNamespace}.{enumType.Name}"))
                .AddArgument(_services);
            }

            foreach (var serializer in _serializers)
            {
                body.AddMethodCall()
                .SetMethodName(TypeNames.AddSingleton)
                .AddGeneric(TypeNames.ISerializer)
                .AddGeneric(serializer)
                .AddArgument(_services);
            }

            RuntimeTypeInfo stringTypeInfo = new RuntimeTypeInfo(TypeNames.String);

            foreach (var scalar in descriptor.TypeDescriptors.OfType <ScalarTypeDescriptor>())
            {
                if (scalar.RuntimeType.Equals(stringTypeInfo) &&
                    scalar.SerializationType.Equals(stringTypeInfo) &&
                    !BuiltInScalarNames.IsBuiltInScalar(scalar.Name))
                {
                    body.AddMethodCall()
                    .SetMethodName(TypeNames.AddSingleton)
                    .AddGeneric(TypeNames.ISerializer)
                    .AddArgument(_services)
                    .AddArgument(MethodCallBuilder
                                 .Inline()
                                 .SetNew()
                                 .SetMethodName(TypeNames.StringSerializer)
                                 .AddArgument(scalar.Name.AsStringToken()));
                }
            }

            foreach (var inputTypeDescriptor in descriptor.TypeDescriptors
                     .Where(x => x.Kind is TypeKind.Input))
            {
                var formatter =
                    CreateInputValueFormatter(
                        (InputObjectTypeDescriptor)inputTypeDescriptor.NamedType());

                body.AddMethodCall()
                .SetMethodName(TypeNames.AddSingleton)
                .AddGeneric(TypeNames.ISerializer)
                .AddGeneric($"{rootNamespace}.{formatter}")
                .AddArgument(_services);
            }

            body.AddCode(RegisterSerializerResolver());

            body.AddEmptyLine();

            foreach (var operation in descriptor.Operations)
            {
                if (!(operation.ResultTypeReference is InterfaceTypeDescriptor typeDescriptor))
                {
                    continue;
                }

                TransportType operationKind = operation switch
                {
                    SubscriptionOperationDescriptor => profile.Subscription,
                    QueryOperationDescriptor => profile.Query,
                    MutationOperationDescriptor => profile.Mutation,
                    _ => throw ThrowHelper.DependencyInjection_InvalidOperationKind(operation)
                };

                string connectionKind = operationKind switch
                {
                    TransportType.Http => TypeNames.IHttpConnection,
                    TransportType.WebSocket => TypeNames.IWebSocketConnection,
                    TransportType.InMemory => TypeNames.IInMemoryConnection,
                    { } v => throw ThrowHelper.DependencyInjection_InvalidTransportType(v)
                };

                string operationName          = operation.Name;
                string fullName               = operation.RuntimeType.ToString();
                string operationInterfaceName = operation.InterfaceType.ToString();
                string resultInterface        = typeDescriptor.RuntimeType.ToString();

                // The factories are generated based on the concrete result type, which is the
                // only implementee of the result type interface.

                var factoryName =
                    CreateResultFactoryName(
                        typeDescriptor.ImplementedBy.First().RuntimeType.Name);

                var builderName = CreateResultBuilderName(operationName);
                body.AddCode(
                    RegisterOperation(
                        settings,
                        connectionKind,
                        fullName,
                        operationInterfaceName,
                        resultInterface,
                        $"{CreateStateNamespace(operation.RuntimeType.Namespace)}.{factoryName}",
                        $"{CreateStateNamespace(operation.RuntimeType.Namespace)}.{builderName}"));
            }

            if (settings.IsStoreEnabled())
            {
                body.AddCode(
                    MethodCallBuilder
                    .New()
                    .SetMethodName(TypeNames.AddSingleton)
                    .AddGeneric(TypeNames.IEntityIdSerializer)
                    .AddGeneric(descriptor.EntityIdFactoryDescriptor.Type.ToString())
                    .AddArgument(_services));
            }

            body.AddCode(
                MethodCallBuilder
                .New()
                .SetMethodName(TypeNames.AddSingleton)
                .AddGeneric(descriptor.ClientDescriptor.RuntimeType.ToString())
                .AddArgument(_services));

            body.AddCode(
                MethodCallBuilder
                .New()
                .SetMethodName(TypeNames.AddSingleton)
                .AddGeneric(descriptor.ClientDescriptor.InterfaceType.ToString())
                .AddArgument(_services)
                .AddArgument(LambdaBuilder
                             .New()
                             .AddArgument(_sp)
                             .SetCode(MethodCallBuilder
                                      .Inline()
                                      .SetMethodName(TypeNames.GetRequiredService)
                                      .AddGeneric(descriptor.ClientDescriptor.RuntimeType.ToString())
                                      .AddArgument(_sp))));

            body.AddLine($"return {_services};");

            return(body);
        }
コード例 #19
0
        private static ICode GenerateClientServiceProviderFactory(
            DependencyInjectionDescriptor descriptor)
        {
            CodeBlockBuilder codeBuilder = CodeBlockBuilder.New();

            if (descriptor.TransportProfiles.Count == 1)
            {
                return(codeBuilder
                       .AddCode(
                           MethodCallBuilder
                           .New()
                           .SetMethodName("ConfigureClient" + descriptor.TransportProfiles[0].Name)
                           .AddArgument(_sp)
                           .AddArgument(_serviceCollection)
                           .AddArgument(_strategy))
                       .AddEmptyLine()
                       .AddCode(MethodCallBuilder
                                .New()
                                .SetReturn()
                                .SetNew()
                                .SetMethodName("ClientServiceProvider")
                                .SetWrapArguments()
                                .AddArgument(MethodCallBuilder
                                             .Inline()
                                             .SetMethodName(TypeNames.BuildServiceProvider)
                                             .AddArgument(_serviceCollection))));
            }

            IfBuilder ifProfile = IfBuilder.New();

            var enumName = CreateProfileEnumReference(descriptor);

            for (var index = 0; index < descriptor.TransportProfiles.Count; index++)
            {
                TransportProfile profile   = descriptor.TransportProfiles[index];
                IfBuilder        currentIf = ifProfile;
                if (index != 0)
                {
                    currentIf = IfBuilder.New();
                    ifProfile.AddIfElse(currentIf);
                }

                currentIf
                .SetCondition($"{_profile} == {enumName}.{profile.Name}")
                .AddCode(
                    MethodCallBuilder
                    .New()
                    .SetMethodName("ConfigureClient" + profile.Name)
                    .AddArgument(_sp)
                    .AddArgument(_serviceCollection)
                    .AddArgument(_strategy));
            }

            return(codeBuilder
                   .AddCode(ifProfile)
                   .AddEmptyLine()
                   .AddCode(MethodCallBuilder
                            .New()
                            .SetReturn()
                            .SetNew()
                            .SetMethodName("ClientServiceProvider")
                            .SetWrapArguments()
                            .AddArgument(MethodCallBuilder
                                         .Inline()
                                         .SetMethodName(TypeNames.BuildServiceProvider)
                                         .AddArgument(_serviceCollection))));
        }
コード例 #20
0
        private static ICode GenerateEntityHandlerIfClause(
            ObjectTypeDescriptor objectTypeDescriptor,
            bool isNonNullable)
        {
            var dataMapperName =
                GetFieldName(
                    CreateEntityMapperName(
                        objectTypeDescriptor.RuntimeType.Name,
                        objectTypeDescriptor.Name));

            MethodCallBuilder constructorCall = MethodCallBuilder
                                                .New()
                                                .SetReturn()
                                                .SetWrapArguments()
                                                .SetMethodName(dataMapperName, "Map");

            MethodCallBuilder argument = MethodCallBuilder
                                         .Inline()
                                         .SetMethodName(_snapshot, "GetEntity")
                                         .AddGeneric(CreateEntityType(
                                                         objectTypeDescriptor.Name,
                                                         objectTypeDescriptor.RuntimeType.NamespaceWithoutGlobal)
                                                     .ToString())
                                         .AddArgument(isNonNullable ? _entityId : $"{_entityId}.Value");

            constructorCall.AddArgument(
                NullCheckBuilder
                .New()
                .SetDetermineStatement(false)
                .SetCondition(argument)
                .SetCode(ExceptionBuilder.Inline(TypeNames.GraphQLClientException)));


            IfBuilder ifCorrectType = IfBuilder
                                      .New()
                                      .AddCode(constructorCall)
                                      .SetCondition(
                MethodCallBuilder
                .Inline()
                .SetMethodName(
                    isNonNullable
                                ? new[]
            {
                _entityId,
                "Name",
                nameof(string.Equals)
            }
                                : new[]
            {
                _entityId,
                "Value",
                "Name",
                nameof(string.Equals)
            })
                .AddArgument(objectTypeDescriptor.Name.AsStringToken())
                .AddArgument(TypeNames.OrdinalStringComparison));

            return(CodeBlockBuilder
                   .New()
                   .AddEmptyLine()
                   .AddCode(ifCorrectType));
        }
コード例 #21
0
        private void AddBuildDataMethod(
            CSharpSyntaxGeneratorSettings settings,
            InterfaceTypeDescriptor resultNamedType,
            ClassBuilder classBuilder)
        {
            var concreteType =
                CreateResultInfoName(
                    resultNamedType.ImplementedBy.First().RuntimeType.Name);

            MethodBuilder buildDataMethod = classBuilder
                                            .AddMethod()
                                            .SetPrivate()
                                            .SetName("BuildData")
                                            .SetReturnType($"({resultNamedType.RuntimeType.Name}, {concreteType})")
                                            .AddParameter(_obj, x => x.SetType(TypeNames.JsonElement));

            if (settings.IsStoreEnabled())
            {
                buildDataMethod.AddCode(
                    AssignmentBuilder
                    .New()
                    .SetLefthandSide($"var {_entityIds}")
                    .SetRighthandSide(MethodCallBuilder
                                      .Inline()
                                      .SetNew()
                                      .SetMethodName(TypeNames.HashSet)
                                      .AddGeneric(TypeNames.EntityId)))
                .AddCode(
                    AssignmentBuilder
                    .New()
                    .SetLefthandSide($"{TypeNames.IEntityStoreSnapshot} {_snapshot}")
                    .SetRighthandSide("default!"));
            }

            buildDataMethod.AddEmptyLine();


            CodeBlockBuilder storeUpdateBody = CodeBlockBuilder.New();

            if (settings.IsStoreEnabled())
            {
                foreach (PropertyDescriptor property in
                         resultNamedType.Properties.Where(prop => prop.Type.IsOrContainsEntity()))
                {
                    var variableName = $"{GetParameterName(property.Name)}Id";

                    buildDataMethod
                    .AddCode(AssignmentBuilder
                             .New()
                             .SetLefthandSide(CodeBlockBuilder
                                              .New()
                                              .AddCode(property.Type.ToStateTypeReference())
                                              .AddCode(variableName))
                             .SetRighthandSide("default!"));

                    storeUpdateBody
                    .AddCode(AssignmentBuilder
                             .New()
                             .SetLefthandSide(variableName)
                             .SetRighthandSide(BuildUpdateMethodCall(property)));
                }

                storeUpdateBody
                .AddEmptyLine()
                .AddCode(AssignmentBuilder
                         .New()
                         .SetLefthandSide(_snapshot)
                         .SetRighthandSide($"{_session}.CurrentSnapshot"));

                buildDataMethod
                .AddCode(MethodCallBuilder
                         .New()
                         .SetMethodName(_entityStore, "Update")
                         .AddArgument(LambdaBuilder
                                      .New()
                                      .AddArgument(_session)
                                      .SetBlock(true)
                                      .SetCode(storeUpdateBody)));
            }

            buildDataMethod
            .AddEmptyLine()
            .AddCode(
                AssignmentBuilder
                .New()
                .SetLefthandSide($"var {_resultInfo}")
                .SetRighthandSide(
                    CreateResultInfoMethodCall(settings, resultNamedType, concreteType)))
            .AddEmptyLine()
            .AddCode(
                TupleBuilder
                .Inline()
                .SetDetermineStatement(true)
                .SetReturn()
                .AddMember(MethodCallBuilder
                           .Inline()
                           .SetMethodName(_resultDataFactory, "Create")
                           .AddArgument(_resultInfo))
                .AddMember(_resultInfo));
        }
コード例 #22
0
        private void AddArrayHandler(
            CSharpSyntaxGeneratorSettings settings,
            ClassBuilder classBuilder,
            ConstructorBuilder constructorBuilder,
            MethodBuilder methodBuilder,
            ListTypeDescriptor listTypeDescriptor,
            HashSet <string> processed,
            bool isNonNullable)
        {
            methodBuilder
            .AddParameter(_list)
            .SetType(listTypeDescriptor.ToStateTypeReference());

            if (settings.IsStoreEnabled())
            {
                methodBuilder
                .AddParameter(_snapshot)
                .SetType(TypeNames.IEntityStoreSnapshot);
            }

            var listVarName = GetParameterName(listTypeDescriptor.Name) + "s";

            methodBuilder.AddCode(EnsureProperNullability(_list, isNonNullable));

            methodBuilder.AddCode(
                AssignmentBuilder
                .New()
                .SetLefthandSide($"var {listVarName}")
                .SetRighthandSide(
                    CodeBlockBuilder
                    .New()
                    .AddCode("new ")
                    .AddCode(TypeNames.List)
                    .AddCode("<")
                    .AddCode(
                        listTypeDescriptor.InnerType.ToTypeReference().SkipTrailingSpace())
                    .AddCode(">")
                    .AddCode("()")));
            methodBuilder.AddEmptyLine();

            ForEachBuilder forEachBuilder = ForEachBuilder
                                            .New()
                                            .SetLoopHeader(
                CodeBlockBuilder
                .New()
                .AddCode(listTypeDescriptor.InnerType.ToStateTypeReference())
                .AddCode($"{_child} in {_list}"))
                                            .AddCode(
                MethodCallBuilder
                .New()
                .SetMethodName(listVarName, nameof(List <object> .Add))
                .AddArgument(MethodCallBuilder
                             .Inline()
                             .SetMethodName(MapMethodNameFromTypeName(listTypeDescriptor.InnerType))
                             .AddArgument(_child)
                             .If(settings.IsStoreEnabled(), x => x.AddArgument(_snapshot))));

            methodBuilder
            .AddCode(forEachBuilder)
            .AddEmptyLine()
            .AddCode($"return {listVarName};");

            AddMapMethod(
                settings,
                listVarName,
                listTypeDescriptor.InnerType,
                classBuilder,
                constructorBuilder,
                processed);
        }
コード例 #23
0
        private ICode FormatSpecificEntityIdBody(EntityIdDescriptor entity)
        {
            var body = CodeBlockBuilder
                       .New();

            body.AddAssigment($"using var {_writer}")
            .SetRighthandSide(
                MethodCallBuilder
                .Inline()
                .SetNew()
                .SetMethodName(TypeNames.ArrayWriter));

            body.AddAssigment($"using var {_jsonWriter}")
            .SetRighthandSide(
                MethodCallBuilder
                .Inline()
                .SetNew()
                .SetMethodName(TypeNames.Utf8JsonWriter)
                .AddArgument(_writer)
                .AddArgument(_options));

            body.AddMethodCall()
            .SetMethodName(_jsonWriter, nameof(Utf8JsonWriter.WriteStartObject));

            body.AddEmptyLine();

            body.AddMethodCall()
            .SetMethodName(_jsonWriter, nameof(Utf8JsonWriter.WriteString))
            .AddArgument(WellKnownNames.TypeName.AsStringToken())
            .AddArgument($"{_entityId}.Name");

            body.AddEmptyLine();

            if (entity.Fields.Count == 1)
            {
                ScalarEntityIdDescriptor?field = entity.Fields[0];

                body.AddMethodCall()
                .SetMethodName(_jsonWriter, GetWriteMethod(field))
                .AddArgument(field.Name.AsStringToken())
                .AddArgument($"({field.SerializationType}){_entityId}.Value");
            }
            else
            {
                body.AddAssigment($"var {_entityIdValues}")
                .SetRighthandSide(CodeBlockBuilder
                                  .New()
                                  .AddCode("(")
                                  .AddCode(TupleBuilder
                                           .New()
                                           .AddMemberRange(
                                               entity.Fields.Select(x => x.SerializationType.ToString())))
                                  .AddCode($"){_entityId}.Value"));
                body.AddEmptyLine();

                for (var index = 0; index < entity.Fields.Count; index++)
                {
                    ScalarEntityIdDescriptor field = entity.Fields[index];

                    body.AddMethodCall()
                    .SetMethodName(_jsonWriter, GetWriteMethod(field))
                    .AddArgument(field.Name.AsStringToken())
                    .AddArgument($"{_entityIdValues}.Item{index + 1}");
                    body.AddEmptyLine();
                }
            }

            body.AddMethodCall()
            .SetMethodName(_jsonWriter, nameof(Utf8JsonWriter.WriteEndObject));

            body.AddMethodCall()
            .SetMethodName(_jsonWriter, nameof(Utf8JsonWriter.Flush));

            body.AddEmptyLine();

            body.AddMethodCall()
            .SetReturn()
            .SetMethodName(TypeNames.EncodingUtf8, nameof(Encoding.UTF8.GetString))
            .AddArgument(MethodCallBuilder.Inline().SetMethodName(_writer, "GetInternalBuffer"))
            .AddArgument("0")
            .AddArgument($"{_writer}.Length");

            return(body);
        }
コード例 #24
0
        private void AddEntityDataTypeDeserializerToMethod(
            MethodBuilder methodBuilder,
            InterfaceTypeDescriptor interfaceTypeDescriptor)
        {
            methodBuilder.AddCode(
                AssignmentBuilder
                .New()
                .SetLefthandSide($"var {_typename}")
                .SetRighthandSide(MethodCallBuilder
                                  .Inline()
                                  .SetMethodName(
                                      _obj,
                                      "Value",
                                      nameof(JsonElement.GetProperty))
                                  .AddArgument(WellKnownNames.TypeName.AsStringToken())
                                  .Chain(x => x.SetMethodName(nameof(JsonElement.GetString)))));

            foreach (ObjectTypeDescriptor concreteType in interfaceTypeDescriptor.ImplementedBy)
            {
                ICode builder;
                if (concreteType.IsEntity())
                {
                    builder = CodeBlockBuilder
                              .New()
                              .AddCode(
                        AssignmentBuilder
                        .New()
                        .SetLefthandSide($"{TypeNames.EntityId} {_entityId}")
                        .SetRighthandSide(
                            MethodCallBuilder
                            .Inline()
                            .SetMethodName(_idSerializer, "Parse")
                            .AddArgument($"{_obj}.Value")))
                              .AddCode(CreateUpdateEntityStatement(concreteType)
                                       .AddCode(MethodCallBuilder
                                                .New()
                                                .SetReturn()
                                                .SetNew()
                                                .SetMethodName(TypeNames.EntityIdOrData)
                                                .AddArgument(_entityId)));
                }
                else
                {
                    builder =
                        MethodCallBuilder
                        .New()
                        .SetNew()
                        .SetReturn()
                        .SetMethodName(TypeNames.EntityIdOrData)
                        .AddArgument(CreateBuildDataStatement(concreteType)
                                     .SetDetermineStatement(false)
                                     .SetNew());
                }

                methodBuilder
                .AddEmptyLine()
                .AddCode(IfBuilder
                         .New()
                         .SetCondition(
                             $"typename?.Equals(\"{concreteType.Name}\", " +
                             $"{TypeNames.OrdinalStringComparison}) ?? false")
                         .AddCode(builder));
            }

            methodBuilder
            .AddEmptyLine()
            .AddCode(ExceptionBuilder.New(TypeNames.NotSupportedException));
        }
コード例 #25
0
ファイル: MethodEmitter.cs プロジェクト: yaram/SharpVk
        private static void EmitActions(CodeBlockBuilder body, List <MethodAction> actions)
        {
            foreach (var action in actions.OfType <DeclarationAction>())
            {
                body.EmitVariableDeclaration(action.MemberType, action.MemberName, Default(action.MemberType));
            }

            foreach (var action in actions.OrderBy(x => x.Priority))
            {
                if (action is AssignAction assignAction)
                {
                    if (assignAction.IsLoop)
                    {
                        void BuildAssignBlock(CodeBlockBuilder ifBlock)
                        {
                            var fieldPointerName = assignAction.FieldPointerName ?? "fieldPointer";

                            if (assignAction.IsArray)
                            {
                                ifBlock.EmitVariableDeclaration("var", fieldPointerName, NewArray(assignAction.MemberType, Cast("uint", assignAction.LengthExpression)));
                            }
                            else
                            {
                                string allocationType = assignAction.MemberType.EndsWith("*")
                                                            ? "IntPtr"
                                                            : assignAction.MemberType;

                                ifBlock.EmitVariableDeclaration("var", fieldPointerName, Cast(assignAction.MemberType + "*", Call(StaticCall("Interop.HeapUtil", $"AllocateAndClear<{allocationType}>", assignAction.LengthExpression), "ToPointer")));
                            }

                            ifBlock.EmitForLoop(init => init.EmitVariableDeclaration("int", assignAction.IndexName, Literal(0)),
                                                LessThan(Variable(assignAction.IndexName), Cast("uint", assignAction.LengthExpression)),
                                                after => after.EmitStatement(assignAction.IndexName + "++"),
                                                loop =>
                            {
                                EmitMarshalAction(loop, assignAction, Index(Variable(fieldPointerName), Variable(assignAction.IndexName)));
                            });

                            ifBlock.EmitAssignment(assignAction.TargetExpression, Variable(fieldPointerName));
                        }

                        if (assignAction.NullCheckExpression != null)
                        {
                            body.EmitIfBlock(assignAction.NullCheckExpression,
                                             BuildAssignBlock,
                                             elseBlock =>
                            {
                                elseBlock.EmitAssignment(assignAction.TargetExpression, Null);
                            });
                        }
                        else
                        {
                            BuildAssignBlock(body);
                        }
                    }
                    else
                    {
                        EmitMarshalAction(body, assignAction, assignAction.TargetExpression);
                    }
                }
                else if (action is InvokeAction invokeAction)
                {
                    var paramNames = (invokeAction.Parameters ?? Enumerable.Empty <Action <ExpressionBuilder> >().ToArray());

                    Action <ExpressionBuilder> invokeExpression = null;

                    if (invokeAction.LookupDelegate)
                    {
                        if (invokeAction.DelegateName != null)
                        {
                            body.EmitVariableDeclaration(invokeAction.DelegateName, "commandDelegate", Call(Variable("commandCache"), $"GetCommandDelegate<{invokeAction.DelegateName}>", Literal(invokeAction.MethodName), Literal(invokeAction.LookupScope)));
                        }

                        invokeExpression = DelegateCall(Variable("commandDelegate"), paramNames);
                    }
                    else if (invokeAction.TypeName == null)
                    {
                        invokeExpression = Call(This, invokeAction.MethodName, paramNames);
                    }
                    else
                    {
                        invokeExpression = StaticCall(invokeAction.TypeName, invokeAction.MethodName, paramNames);
                    }

                    if (invokeAction.ReturnName != null)
                    {
                        if (invokeAction.ReturnType != null)
                        {
                            body.EmitVariableDeclaration(invokeAction.ReturnType, invokeAction.ReturnName, invokeExpression);
                        }
                        else
                        {
                            body.EmitAssignment(Variable(invokeAction.ReturnName), invokeExpression);
                        }
                    }
                    else
                    {
                        body.EmitCallExpression(invokeExpression);
                    }
                }
                else if (action is OptionalAction optionalAction)
                {
                    if (optionalAction.ElseActions.Any())
                    {
                        body.EmitIfBlock(optionalAction.CheckExpression,
                                         ifBlock => EmitActions(ifBlock, optionalAction.Actions),
                                         elseBlock => EmitActions(elseBlock, optionalAction.ElseActions));
                    }
                    else
                    {
                        body.EmitIfBlock(optionalAction.CheckExpression,
                                         ifBlock => EmitActions(ifBlock, optionalAction.Actions));
                    }
                }
                else if (action is ValidateAction validationAction)
                {
                    body.EmitIfBlock(StaticCall("SharpVkException", "IsError", Variable(validationAction.VariableName)),
                                     ifBlock =>
                    {
                        ifBlock.EmitThrow(StaticCall("SharpVkException", "Create", Variable(validationAction.VariableName)));
                    });
                }
            }
        }
コード例 #26
0
        protected override void Generate(EntityIdFactoryDescriptor descriptor,
                                         CSharpSyntaxGeneratorSettings settings,
                                         CodeWriter writer,
                                         out string fileName,
                                         out string?path,
                                         out string ns)
        {
            fileName = descriptor.Name;
            path     = State;
            ns       = descriptor.Namespace;

            ClassBuilder classBuilder = ClassBuilder
                                        .New()
                                        .SetAccessModifier(AccessModifier.Public)
                                        .AddImplements(TypeNames.IEntityIdSerializer)
                                        .SetName(fileName);

            classBuilder
            .AddField(_options)
            .SetStatic()
            .SetReadOnly()
            .SetType(TypeNames.JsonWriterOptions)
            .SetValue(CodeBlockBuilder
                      .New()
                      .AddCode(MethodCallBuilder
                               .Inline()
                               .SetNew()
                               .SetMethodName(TypeNames.JsonWriterOptions))
                      .AddCode(CodeInlineBuilder.From("{ Indented = false }")));

            classBuilder
            .AddMethod("Parse")
            .SetAccessModifier(AccessModifier.Public)
            .SetReturnType(TypeNames.EntityId)
            .AddParameter(_obj, x => x.SetType(TypeNames.JsonElement))
            .AddCode(ParseEntityIdBody(descriptor));

            classBuilder
            .AddMethod("Format")
            .SetAccessModifier(AccessModifier.Public)
            .SetReturnType(TypeNames.String)
            .AddParameter(_entityId, x => x.SetType(TypeNames.EntityId))
            .AddCode(FormatEntityIdBody(descriptor));

            foreach (var entity in descriptor.Entities)
            {
                classBuilder
                .AddMethod($"Parse{entity.Name}EntityId")
                .SetAccessModifier(AccessModifier.Private)
                .SetReturnType(TypeNames.EntityId)
                .AddParameter(_obj, x => x.SetType(TypeNames.JsonElement))
                .AddParameter(_type, x => x.SetType(TypeNames.String))
                .AddCode(ParseSpecificEntityIdBody(entity));

                classBuilder
                .AddMethod($"Format{entity.Name}EntityId")
                .SetAccessModifier(AccessModifier.Private)
                .SetReturnType(TypeNames.String)
                .AddParameter(_entityId, x => x.SetType(TypeNames.EntityId))
                .AddCode(FormatSpecificEntityIdBody(entity));
            }

            classBuilder.Build(writer);
        }