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));
 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()))))));
        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 }
                    })
        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));
        }
Пример #5
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);
        }
Пример #6
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));
        }
Пример #7
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));
        }
Пример #8
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));
        }
Пример #9
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)))));
 }
Пример #10
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);
        }
Пример #11
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))));
        }
        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));
        }
        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));
        }
Пример #14
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);
        }
        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))));
        }
Пример #16
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);
        }
Пример #17
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);
        }