private static AssignmentBuilder CreateDataError(
            string exception = "ex")
        {
            string dict = TypeNames.Dictionary.WithGeneric(
                TypeNames.String,
                TypeNames.Object.MakeNullable());

            string body = "response.Body?.RootElement.ToString()";

            MethodCallBuilder createClientError =
                MethodCallBuilder
                .Inline()
                .SetNew()
                .SetMethodName(TypeNames.ClientError)
                .AddArgument($"{exception}.Message")
                .AddArgument($"exception: {exception}")
                .AddArgument($"extensions: new  {dict} {{ {{ \"body\", {body} }} }}");

            return(AssignmentBuilder.New()
                   .SetLefthandSide("errors")
                   .SetRighthandSide(
                       ArrayBuilder.New()
                       .SetDetermineStatement(false)
                       .SetType(TypeNames.IClientError)
                       .AddAssignment(createClientError)));
        }
예제 #2
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()))))));
예제 #3
0
 private static ICode RegisterWebSocketConnection(string clientName) =>
 MethodCallBuilder
 .New()
 .SetMethodName(TypeNames.AddSingleton)
 .AddArgument(_services)
 .AddArgument(LambdaBuilder
              .New()
              .AddArgument(_sp)
              .SetBlock(true)
              .SetCode(CodeBlockBuilder
                       .New()
                       .AddCode(AssignmentBuilder
                                .New()
                                .SetLefthandSide($"var {_sessionPool}")
                                .SetRighthandSide(MethodCallBuilder
                                                  .Inline()
                                                  .SetMethodName(TypeNames.GetRequiredService)
                                                  .AddGeneric(TypeNames.ISessionPool)
                                                  .AddArgument(_parentServices)))
                       .AddCode(MethodCallBuilder
                                .New()
                                .SetReturn()
                                .SetNew()
                                .SetMethodName(TypeNames.WebSocketConnection)
                                .AddArgument(LambdaBuilder
                                             .New()
                                             .SetCode(MethodCallBuilder
                                                      .Inline()
                                                      .SetMethodName(
                                                          _sessionPool,
                                                          nameof(ISessionPool.CreateAsync))
                                                      .AddArgument(clientName.AsStringToken())
                                                      .AddArgument("default"))))));
예제 #4
0
        protected void AddConstructorAssignedField(
            TypeReferenceBuilder type,
            string fieldName,
            ClassBuilder classBuilder,
            ConstructorBuilder constructorBuilder,
            bool skipNullCheck = false)
        {
            var paramName = fieldName.TrimStart('_');

            classBuilder.AddField(
                FieldBuilder
                .New()
                .SetReadOnly()
                .SetName(fieldName)
                .SetType(type));

            var assignment = AssignmentBuilder
                             .New()
                             .SetLefthandSide(fieldName)
                             .SetRighthandSide(paramName);

            if (!skipNullCheck)
            {
                assignment.AssertNonNull();
            }

            constructorBuilder
            .AddCode(assignment)
            .AddParameter(paramName, b => b.SetType(type));
        }
        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));
        }
        private void AddArrayHandler(
            ClassBuilder classBuilder,
            ConstructorBuilder constructorBuilder,
            MethodBuilder methodBuilder,
            ListTypeDescriptor listTypeDescriptor,
            HashSet <string> processed,
            bool isNonNullable)
        {
            methodBuilder.AddParameter(
                ParameterBuilder.New()
                .SetType(listTypeDescriptor.ToEntityIdBuilder())
                .SetName(ListParamName));
            var listVarName = listTypeDescriptor.Name.WithLowerFirstChar() + "s";

            if (!isNonNullable)
            {
                methodBuilder.AddCode(EnsureProperNullability(ListParamName, isNonNullable));
            }

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

            var loopbuilder = ForEachBuilder.New()
                              .SetLoopHeader(
                CodeBlockBuilder.New()
                .AddCode(listTypeDescriptor.InnerType.ToEntityIdBuilder())
                .AddCode($"child in {ListParamName}"))
                              .AddCode(
                MethodCallBuilder.New()
                .SetPrefix($"{listVarName}.")
                .SetMethodName("Add")
                .AddArgument(
                    BuildMapMethodCall(
                        listTypeDescriptor.InnerType,
                        "child")));

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

            AddMapMethod(
                listVarName,
                listTypeDescriptor.InnerType,
                classBuilder,
                constructorBuilder,
                processed);
        }
예제 #7
0
        private IfBuilder GenerateDataInterfaceIfClause(
            ObjectTypeDescriptor objectTypeDescriptor,
            bool isNonNullable,
            string variableName)
        {
            ICode ifCondition = MethodCallBuilder
                                .Inline()
                                .SetMethodName(
                _dataParameterName.MakeNullable(!isNonNullable),
                WellKnownNames.TypeName,
                nameof(string.Equals))
                                .AddArgument(objectTypeDescriptor.Name.AsStringToken())
                                .AddArgument(TypeNames.OrdinalStringComparison);

            if (!isNonNullable)
            {
                ifCondition = NullCheckBuilder
                              .New()
                              .SetCondition(ifCondition)
                              .SetSingleLine()
                              .SetDetermineStatement(false)
                              .SetCode("false");
            }

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

            foreach (PropertyDescriptor prop in objectTypeDescriptor.Properties)
            {
                var propAccess = $"{_dataParameterName}.{prop.Name}";
                if (prop.Type.IsEntityType() || prop.Type.IsDataType())
                {
                    constructorCall.AddArgument(BuildMapMethodCall(_dataParameterName, prop, true));
                }
                else if (prop.Type.IsNullableType())
                {
                    constructorCall.AddArgument(propAccess);
                }
                else
                {
                    constructorCall
                    .AddArgument(
                        NullCheckBuilder
                        .Inline()
                        .SetCondition(propAccess)
                        .SetCode(ExceptionBuilder.Inline(TypeNames.ArgumentNullException)));
                }
            }

            return(IfBuilder
                   .New()
                   .SetCondition(ifCondition)
                   .AddCode(AssignmentBuilder
                            .New()
                            .SetLefthandSide(variableName)
                            .SetRighthandSide(constructorCall)));
        }
예제 #8
0
        private void AddBuildMethod(
            InterfaceTypeDescriptor resultNamedType,
            ClassBuilder classBuilder)
        {
            var responseParameterName = "response";

            var buildMethod = MethodBuilder
                              .New()
                              .SetAccessModifier(AccessModifier.Public)
                              .SetName("Build")
                              .SetReturnType(
                TypeReferenceBuilder.New()
                .SetName(TypeNames.IOperationResult)
                .AddGeneric(resultNamedType.RuntimeType.Name))
                              .AddParameter(
                ParameterBuilder.New()
                .SetType(
                    TypeReferenceBuilder.New()
                    .SetName(TypeNames.Response)
                    .AddGeneric(TypeNames.JsonDocument)
                    .SetName(TypeNames.Response))
                .SetName(responseParameterName));

            var concreteResultType =
                CreateResultInfoName(resultNamedType.ImplementedBy.First().RuntimeType.Name);

            buildMethod.AddCode(
                AssignmentBuilder.New()
                .SetLefthandSide(
                    $"({resultNamedType.RuntimeType.Name} Result, {concreteResultType} " +
                    "Info)? data")
                .SetRighthandSide("null"));

            buildMethod.AddEmptyLine();
            buildMethod.AddCode(
                IfBuilder.New()
                .SetCondition(
                    ConditionBuilder.New()
                    .Set("response.Body is not null")
                    .And("response.Body.RootElement.TryGetProperty(\"data\"," +
                         $" out {TypeNames.JsonElement} obj)"))
                .AddCode("data = BuildData(obj);"));

            buildMethod.AddEmptyLine();
            buildMethod.AddCode(
                MethodCallBuilder.New()
                .SetPrefix("return new ")
                .SetMethodName(
                    TypeNames.OperationResult.WithGeneric(resultNamedType.RuntimeType.Name))
                .AddArgument("data?.Result")
                .AddArgument("data?.Info")
                .AddArgument(_resultDataFactoryFieldName)
                .AddArgument("null"));

            classBuilder.AddMethod(buildMethod);
        }
 private void WritePropertyAssignments <T>(ICodeContainer <T> codeContainer,
                                           IReadOnlyList <PropertyDescriptor> properties, string entityVarName)
 {
     foreach (PropertyDescriptor property in properties)
     {
         codeContainer.AddCode(
             AssignmentBuilder.New()
             .SetLefthandSide($"{entityVarName}.{property.Name}")
             .SetRighthandSide(BuildUpdateMethodCall(property)));
     }
 }
예제 #10
0
        protected override void Generate(
            CodeWriter writer,
            EntityTypeDescriptor descriptor,
            out string fileName,
            out string?path)
        {
            // Setup class
            fileName = descriptor.RuntimeType.Name;
            path     = State;

            ClassBuilder classBuilder = ClassBuilder
                                        .New()
                                        .SetComment(descriptor.Documentation)
                                        .SetName(fileName);

            ConstructorBuilder constructorBuilder = classBuilder
                                                    .AddConstructor()
                                                    .SetPublic()
                                                    .SetTypeName(fileName);

            // Add Properties to class
            foreach (KeyValuePair <string, PropertyDescriptor> item in descriptor.Properties)
            {
                classBuilder
                .AddProperty(item.Value.Name)
                .SetComment(item.Value.Description)
                .SetType(item.Value.Type.ToStateTypeReference())
                .SetPublic();

                var paramName = item.Value.Name == WellKnownNames.TypeName
                    ? WellKnownNames.TypeName
                    : GetParameterName(item.Value.Name);

                constructorBuilder
                .AddParameter(
                    paramName,
                    x => x.SetType(item.Value.Type.ToStateTypeReference()))
                .AddCode(AssignmentBuilder
                         .New()
                         .SetLefthandSide(
                             (item.Value.Name == WellKnownNames.TypeName
                                ? "this."
                                : string.Empty) +
                             item.Value.Name)
                         .SetRighthandSide(paramName));
            }

            CodeFileBuilder
            .New()
            .SetNamespace(descriptor.RuntimeType.NamespaceWithoutGlobal)
            .AddType(classBuilder)
            .Build(writer);
        }
        private void AddUpdateEntityMethod(
            ClassBuilder classBuilder,
            MethodBuilder methodBuilder,
            INamedTypeDescriptor namedTypeDescriptor,
            HashSet <string> processed)
        {
            methodBuilder.AddCode(
                AssignmentBuilder
                .New()
                .SetLefthandSide($"{TypeNames.EntityId} {_entityId}")
                .SetRighthandSide(
                    MethodCallBuilder
                    .Inline()
                    .SetMethodName(_idSerializer, "Parse")
                    .AddArgument($"{_obj}.Value")));

            methodBuilder.AddCode(
                MethodCallBuilder
                .New()
                .SetMethodName(_entityIds, nameof(List <object> .Add))
                .AddArgument(_entityId));

            methodBuilder.AddEmptyLine();

            if (namedTypeDescriptor is InterfaceTypeDescriptor interfaceTypeDescriptor)
            {
                // If the type is an interface
                foreach (ObjectTypeDescriptor concreteType in interfaceTypeDescriptor.ImplementedBy)
                {
                    methodBuilder
                    .AddEmptyLine()
                    .AddCode(CreateUpdateEntityStatement(concreteType)
                             .AddCode($"return {_entityId};"));
                }

                methodBuilder.AddEmptyLine();
                methodBuilder.AddCode(ExceptionBuilder.New(TypeNames.NotSupportedException));
            }
            else if (namedTypeDescriptor is ObjectTypeDescriptor objectTypeDescriptor)
            {
                BuildTryGetEntityIf(
                    CreateEntityType(
                        objectTypeDescriptor.Name,
                        objectTypeDescriptor.RuntimeType.NamespaceWithoutGlobal))
                .AddCode(CreateEntityConstructorCall(objectTypeDescriptor, false))
                .AddElse(CreateEntityConstructorCall(objectTypeDescriptor, true));

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

            AddRequiredDeserializeMethods(namedTypeDescriptor, classBuilder, processed);
        }
        public static AssignmentBuilder AddAssigment(
            this CodeBlockBuilder builder,
            string assignedTo)
        {
            AssignmentBuilder assignmentBuilder = AssignmentBuilder
                                                  .New()
                                                  .SetLefthandSide(assignedTo);

            builder.AddCode(assignmentBuilder);

            return(assignmentBuilder);
        }
예제 #13
0
        protected override void Generate(
            CodeWriter writer,
            ObjectTypeDescriptor descriptor,
            out string fileName,
            out string?path)
        {
            fileName = descriptor.RuntimeType.Name;
            path     = null;

            ClassBuilder classBuilder = ClassBuilder
                                        .New()
                                        .SetComment(descriptor.Description)
                                        .SetName(fileName)
                                        .AddEquality(fileName, descriptor.Properties);

            ConstructorBuilder constructorBuilder = classBuilder
                                                    .AddConstructor()
                                                    .SetTypeName(fileName);

            foreach (var prop in descriptor.Properties)
            {
                TypeReferenceBuilder propTypeBuilder = prop.Type.ToTypeReference();

                // Add Property to class
                classBuilder
                .AddProperty(prop.Name)
                .SetComment(prop.Description)
                .SetName(prop.Name)
                .SetType(propTypeBuilder)
                .SetPublic();

                // Add initialization of property to the constructor
                var paramName = GetParameterName(prop.Name);
                constructorBuilder
                .AddParameter(paramName, x => x.SetType(propTypeBuilder))
                .AddCode(AssignmentBuilder
                         .New()
                         .SetLefthandSide(
                             (prop.Name.Value is WellKnownNames.TypeName
                                ? "this."
                                : string.Empty) +
                             prop.Name)
                         .SetRighthandSide(paramName));
            }

            classBuilder.AddImplementsRange(descriptor.Implements.Select(x => x.Value));

            CodeFileBuilder
            .New()
            .SetNamespace(descriptor.RuntimeType.NamespaceWithoutGlobal)
            .AddType(classBuilder)
            .Build(writer);
        }
예제 #14
0
 private void WriteEntityLoader <T>(
     ICodeContainer <T> codeContainer,
     string entityTypeName)
 {
     codeContainer.AddCode(
         AssignmentBuilder
         .New()
         .SetLefthandSide($"{entityTypeName} {_entity}")
         .SetRighthandSide(
             MethodCallBuilder
             .Inline()
             .SetMethodName(_entityStore, nameof(IEntityStore.GetOrCreate))
             .AddGeneric(entityTypeName)
             .AddArgument(_entityId)));
 }
        public static AssignmentBuilder AddAssigment(
            this CodeBlockBuilder builder,
            string?assignedTo = null)
        {
            AssignmentBuilder assignmentBuilder = AssignmentBuilder
                                                  .New();

            if (assignedTo is not null)
            {
                assignmentBuilder.SetLefthandSide(assignedTo);
            }

            builder.AddCode(assignmentBuilder);

            return(assignmentBuilder);
        }
예제 #16
0
 private static ICode GenerateMethodBody(DependencyInjectionDescriptor descriptor) =>
 CodeBlockBuilder
 .New()
 .AddMethodCall(x =>
                x.SetMethodName(TypeNames.AddSingleton)
                .AddArgument(_services)
                .AddArgument(LambdaBuilder
                             .New()
                             .SetBlock(true)
                             .AddArgument(_sp)
                             .SetCode(
                                 CodeBlockBuilder
                                 .New()
                                 .AddCode(
                                     AssignmentBuilder
                                     .New()
                                     .SetLefthandSide($"var {_serviceCollection}")
                                     .SetRighthandSide(
                                         MethodCallBuilder
                                         .Inline()
                                         .SetNew()
                                         .SetMethodName(TypeNames.ServiceCollection)))
                                 .AddEmptyLine()
                                 .AddMethodCall(x => x.SetMethodName("ConfigureClient")
                                                .AddArgument(_serviceCollection)
                                                .AddArgument(_sp)
                                                .AddArgument(_strategy))
                                 .AddEmptyLine()
                                 .AddCode(MethodCallBuilder
                                          .New()
                                          .SetReturn()
                                          .SetNew()
                                          .SetMethodName("ClientServiceProvider")
                                          .SetWrapArguments()
                                          .AddArgument(MethodCallBuilder
                                                       .Inline()
                                                       .SetMethodName(TypeNames.BuildServiceProvider)
                                                       .AddArgument(_serviceCollection))))))
 .AddEmptyLine()
 .ForEach(
     descriptor.Operations,
     (builder, operation) =>
     builder.AddCode(ForwardSingletonToClientServiceProvider(operation.Name)))
 .AddEmptyLine()
 .AddCode(ForwardSingletonToClientServiceProvider(descriptor.Name))
 .AddEmptyLine()
 .AddLine($"return {_services};");
예제 #17
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);
        }
예제 #18
0
        protected override void Generate(
            CodeWriter writer,
            ObjectTypeDescriptor descriptor,
            out string fileName)
        {
            fileName = descriptor.RuntimeType.Name;
            ClassBuilder classBuilder = ClassBuilder
                                        .New()
                                        .SetName(fileName);

            ConstructorBuilder constructorBuilder = classBuilder
                                                    .AddConstructor()
                                                    .SetTypeName(fileName);

            foreach (var prop in descriptor.Properties)
            {
                TypeReferenceBuilder propTypeBuilder = prop.Type.ToBuilder();

                // Add Property to class
                classBuilder
                .AddProperty(prop.Name)
                .SetName(prop.Name)
                .SetType(propTypeBuilder)
                .SetPublic()
                .SetValue(prop.Type.IsNullableType() ? "default!" : null);

                // Add initialization of property to the constructor
                var paramName = GetParameterName(prop.Name);
                constructorBuilder
                .AddParameter(paramName, x => x.SetType(propTypeBuilder))
                .AddCode(AssignmentBuilder
                         .New()
                         .SetLefthandSide(prop.Name)
                         .SetRighthandSide(paramName));
            }

            classBuilder.AddImplementsRange(descriptor.Implements.Select(x => x.Value));

            CodeFileBuilder
            .New()
            .SetNamespace(descriptor.RuntimeType.NamespaceWithoutGlobal)
            .AddType(classBuilder)
            .Build(writer);
        }
예제 #19
0
        private static void AddInjectedSerializers(
            OperationDescriptor descriptor,
            ConstructorBuilder constructorBuilder,
            ClassBuilder classBuilder)
        {
            var neededSerializers = descriptor
                                    .Arguments
                                    .GroupBy(x => x.Type.Name)
                                    .ToDictionary(x => x.Key, x => x.First());

            if (!neededSerializers.Any())
            {
                return;
            }

            constructorBuilder
            .AddParameter(_serializerResolver)
            .SetType(TypeNames.ISerializerResolver);

            foreach (var property in neededSerializers.Values)
            {
                if (property.Type.GetName().Value is { } name)
                {
                    var fieldName = $"{GetFieldName(name)}Formatter";
                    constructorBuilder
                    .AddCode(
                        AssignmentBuilder
                        .New()
                        .SetLefthandSide(fieldName)
                        .SetRighthandSide(
                            MethodCallBuilder
                            .Inline()
                            .SetMethodName(
                                _serializerResolver,
                                "GetInputValueFormatter")
                            .AddArgument(name.AsStringToken())));

                    classBuilder
                    .AddField()
                    .SetName(fieldName)
                    .SetAccessModifier(AccessModifier.Private)
                    .SetType(TypeNames.IInputValueFormatter)
                    .SetReadOnly();
                }
예제 #20
0
 private static ICode GenerateMethodBody(
     CSharpSyntaxGeneratorSettings settings,
     DependencyInjectionDescriptor descriptor) =>
 CodeBlockBuilder
 .New()
 .AddCode(
     AssignmentBuilder
     .New()
     .SetLefthandSide($"var {_serviceCollection}")
     .SetRighthandSide(MethodCallBuilder
                       .Inline()
                       .SetNew()
                       .SetMethodName(TypeNames.ServiceCollection)))
 .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)
                .AddArgument(_serviceCollection));
예제 #21
0
        private static ICode BuildProperty(
            ITypeDescriptor type,
            string propertyName)
        {
            return(BuildPropertyInternal(type, propertyName, true));

            ICode BuildPropertyInternal(
                ITypeDescriptor currentType,
                string variableName,
                bool isNullable)
            {
                ICode check = currentType switch
                {
                    NonNullTypeDescriptor d =>
                    BuildPropertyInternal(d.InnerType, variableName, false),
                    INamedTypeDescriptor => AssignmentBuilder
                    .New()
                    .SetLefthandSide(HashCodeBuilder.VariableName)
                    .SetOperator("^=")
                    .SetRighthandSide(MethodCallBuilder
                                      .Inline()
                                      .SetPrefix($"{HashCodeBuilder.Prime} * ")
                                      .SetMethodName(variableName, nameof(GetHashCode))),
                    ListTypeDescriptor d => ForEachBuilder
                    .New()
                    .SetLoopHeader($"var {variableName}_elm in {variableName}")
                    .AddCode(BuildPropertyInternal(d.InnerType, variableName + "_elm", true)),
                    _ => throw new ArgumentOutOfRangeException()
                };

                if (isNullable && currentType is not NonNullTypeDescriptor)
                {
                    return(IfBuilder
                           .New()
                           .SetCondition($"!({variableName} is null)")
                           .AddCode(check));
                }

                return(check);
            }
        }
    }
예제 #22
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));
        }
예제 #23
0
        private void AddArrayHandler(
            ClassBuilder classBuilder,
            MethodBuilder methodBuilder,
            ListTypeDescriptor listTypeDescriptor,
            HashSet <string> processed)
        {
            var listVarName = listTypeDescriptor.Name.WithLowerFirstChar() + "s";

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

            methodBuilder.AddCode(
                ForEachBuilder.New()
                .SetLoopHeader(
                    $"{TypeNames.JsonElement} child in {_objParamName}.Value.EnumerateArray()")
                .AddCode(
                    MethodCallBuilder.New()
                    .SetPrefix($"{listVarName}.")
                    .SetMethodName("Add")
                    .AddArgument(
                        BuildUpdateMethodCall(listTypeDescriptor.InnerType, "child"))));

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

            AddDeserializeMethod(listTypeDescriptor.InnerType, classBuilder, processed);
        }
예제 #24
0
        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 = CreateBuildDataStatement(concreteType)
                                                    .SetReturn();

                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));
        }
        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");

            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
                {
                    constructorCall.AddArgument($"{matchedTypeName}.{prop.Name}");
                }
            }

            return(IfBuilder
                   .New()
                   .SetCondition($"{_dataParameterName} is {dataTypeName} {matchedTypeName}")
                   .AddCode(
                       AssignmentBuilder
                       .New()
                       .SetLefthandSide(variableName)
                       .SetRighthandSide(constructorCall)));
        }
 private static ICode GenerateMethodBody(DependencyInjectionDescriptor descriptor) =>
 CodeBlockBuilder.New()
 .AddMethodCall(x =>
                x.SetMethodName(TypeNames.AddSingleton)
                .AddArgument("services")
                .AddArgument(LambdaBuilder.New()
                             .SetBlock(true)
                             .AddArgument("sp")
                             .SetCode(
                                 CodeBlockBuilder.New()
                                 .AddCode(
                                     AssignmentBuilder.New()
                                     .SetLefthandSide("var serviceCollection")
                                     .SetRighthandSide(
                                         $"new {TypeNames.ServiceCollection}()"))
                                 .AddEmptyLine()
                                 .AddMethodCall(x => x.SetMethodName("ConfigureClient")
                                                .AddArgument("serviceCollection")
                                                .AddArgument("sp")
                                                .AddArgument("strategy"))
                                 .AddEmptyLine()
                                 .AddCode(MethodCallBuilder.New()
                                          .SetPrefix("return new ")
                                          .SetWrapArguments()
                                          .SetMethodName("ClientServiceProvider")
                                          .AddArgument(MethodCallBuilder.New()
                                                       .SetMethodName(TypeNames.BuildServiceProvider)
                                                       .SetDetermineStatement(false)
                                                       .AddArgument("serviceCollection"))))))
 .AddEmptyLine()
 .ForEach(
     descriptor.Operations,
     (builder, operation) =>
     builder.AddCode(ForwardSingletonToClientServiceProvider(operation.Name)))
 .AddEmptyLine()
 .AddCode(ForwardSingletonToClientServiceProvider(descriptor.Name))
 .AddEmptyLine()
 .AddLine("return services;");
예제 #27
0
        protected override void Generate(ITypeDescriptor typeDescriptor,
                                         CSharpSyntaxGeneratorSettings settings,
                                         CodeWriter writer,
                                         out string fileName,
                                         out string?path,
                                         out string ns)
        {
            ComplexTypeDescriptor complexTypeDescriptor =
                typeDescriptor as ComplexTypeDescriptor ??
                throw new InvalidOperationException(
                          "A result entity mapper can only be generated for complex types");

            var className = CreateResultInfoName(complexTypeDescriptor.RuntimeType.Name);

            fileName = className;
            path     = State;
            ns       = CreateStateNamespace(complexTypeDescriptor.RuntimeType.NamespaceWithoutGlobal);

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

            ConstructorBuilder constructorBuilder = classBuilder
                                                    .AddConstructor()
                                                    .SetTypeName(complexTypeDescriptor.RuntimeType.Name);

            foreach (var prop in complexTypeDescriptor.Properties)
            {
                TypeReferenceBuilder propTypeBuilder = prop.Type.ToStateTypeReference();

                // Add Property to class
                classBuilder
                .AddProperty(prop.Name)
                .SetComment(prop.Description)
                .SetType(propTypeBuilder)
                .SetPublic();

                // Add initialization of property to the constructor
                var paramName = GetParameterName(prop.Name);
                constructorBuilder.AddParameter(paramName).SetType(propTypeBuilder);
                constructorBuilder.AddCode(
                    AssignmentBuilder
                    .New()
                    .SetLefthandSide(prop.Name)
                    .SetRighthandSide(paramName));
            }

            classBuilder
            .AddProperty("EntityIds")
            .SetType(TypeNames.IReadOnlyCollection.WithGeneric(TypeNames.EntityId))
            .AsLambda(settings.IsStoreEnabled()
                    ? CodeInlineBuilder.From(_entityIds)
                    : MethodCallBuilder.Inline()
                      .SetMethodName(TypeNames.Array, "Empty")
                      .AddGeneric(TypeNames.EntityId));

            classBuilder
            .AddProperty("Version")
            .SetType(TypeNames.UInt64)
            .AsLambda(settings.IsStoreEnabled() ? _version : "0");

            if (settings.IsStoreEnabled())
            {
                AddConstructorAssignedField(
                    TypeNames.IReadOnlyCollection.WithGeneric(TypeNames.EntityId),
                    _entityIds,
                    entityIds,
                    classBuilder,
                    constructorBuilder);

                AddConstructorAssignedField(
                    TypeNames.UInt64,
                    _version,
                    version,
                    classBuilder,
                    constructorBuilder,
                    true);
            }

            // WithVersion
            classBuilder
            .AddMethod("WithVersion")
            .SetAccessModifier(AccessModifier.Public)
            .SetReturnType(TypeNames.IOperationResultDataInfo)
            .AddParameter(version, x => x.SetType(TypeNames.UInt64))
            .AddCode(MethodCallBuilder
                     .New()
                     .SetReturn()
                     .SetNew()
                     .SetMethodName(className)
                     .AddArgumentRange(
                         complexTypeDescriptor.Properties.Select(x => x.Name.Value))
                     .If(settings.IsStoreEnabled(),
                         x => x.AddArgument(_entityIds).AddArgument(version)));

            classBuilder.Build(writer);
        }
예제 #28
0
        protected override void Generate(
            CodeWriter writer,
            DataTypeDescriptor descriptor,
            out string fileName)
        {
            fileName = descriptor.RuntimeType.Name;
            AbstractTypeBuilder typeBuilder;
            ConstructorBuilder? constructorBuilder = null;

            if (descriptor.IsInterface)
            {
                typeBuilder = InterfaceBuilder
                              .New()
                              .SetName(fileName);

                typeBuilder
                .AddProperty(__typename)
                .SetType(TypeNames.String);
            }
            else
            {
                ClassBuilder classBuilder = ClassBuilder
                                            .New()
                                            .SetName(fileName);

                typeBuilder = classBuilder;

                classBuilder
                .AddProperty(__typename)
                .SetPublic()
                .SetType(TypeNames.String);

                constructorBuilder = classBuilder
                                     .AddConstructor()
                                     .SetTypeName(fileName);

                constructorBuilder
                .AddParameter(_typename)
                .SetType(TypeNames.String)
                .SetName(_typename);

                constructorBuilder
                .AddCode(
                    AssignmentBuilder
                    .New()
                    .SetLefthandSide(__typename)
                    .SetRighthandSide(_typename)
                    .AssertNonNull());
            }

            // Add Properties to class
            foreach (PropertyDescriptor property in descriptor.Properties)
            {
                TypeReferenceBuilder propertyType = property.Type.Kind switch
                {
                    TypeKind.LeafType => property.Type.ToBuilder(),
                    TypeKind.DataType => property.Type.ToBuilder(property.Type.Name),
                    TypeKind.EntityType => property.Type.ToEntityIdBuilder(),
                    _ => throw new ArgumentOutOfRangeException()
                };

                typeBuilder
                .AddProperty(property.Name)
                .SetType(propertyType)
                .SetPublic();

                var parameterName = GetParameterName(property.Name);

                constructorBuilder?
                .AddParameter(parameterName)
                .SetType(propertyType)
                .SetDefault("null");

                constructorBuilder?
                .AddCode(AssignmentBuilder
                         .New()
                         .SetLefthandSide(property.Name)
                         .SetRighthandSide(parameterName));
            }

            // implement interfaces
            typeBuilder.AddImplementsRange(descriptor.Implements.Select(CreateDataTypeName));

            CodeFileBuilder
            .New()
            .SetNamespace(descriptor.RuntimeType.NamespaceWithoutGlobal)
            .AddType(typeBuilder)
            .Build(writer);
        }
    }
        protected override void Generate(ITypeDescriptor typeDescriptor,
                                         CSharpSyntaxGeneratorSettings settings,
                                         CodeWriter writer,
                                         out string fileName,
                                         out string?path,
                                         out string ns)
        {
            ComplexTypeDescriptor descriptor =
                typeDescriptor as ComplexTypeDescriptor ??
                throw new InvalidOperationException(
                          "A result data factory can only be generated for complex types");

            fileName = CreateResultFactoryName(descriptor.RuntimeType.Name);
            path     = State;
            ns       = CreateStateNamespace(descriptor.RuntimeType.NamespaceWithoutGlobal);

            ClassBuilder classBuilder =
                ClassBuilder
                .New()
                .SetName(fileName)
                .AddImplements(
                    TypeNames.IOperationResultDataFactory.WithGeneric(descriptor.RuntimeType));

            ConstructorBuilder constructorBuilder = classBuilder
                                                    .AddConstructor()
                                                    .SetTypeName(descriptor.Name);

            if (settings.IsStoreEnabled())
            {
                AddConstructorAssignedField(
                    TypeNames.IEntityStore,
                    _entityStore,
                    entityStore,
                    classBuilder,
                    constructorBuilder);
            }

            MethodCallBuilder returnStatement = MethodCallBuilder
                                                .New()
                                                .SetReturn()
                                                .SetNew()
                                                .SetMethodName(descriptor.RuntimeType.Name);

            foreach (PropertyDescriptor property in descriptor.Properties)
            {
                returnStatement
                .AddArgument(BuildMapMethodCall(settings, _info, property));
            }

            IfBuilder ifHasCorrectType = IfBuilder
                                         .New()
                                         .SetCondition(
                $"{_dataInfo} is {CreateResultInfoName(descriptor.RuntimeType.Name)} {_info}")
                                         .AddCode(returnStatement);

            MethodBuilder createMethod = classBuilder
                                         .AddMethod("Create")
                                         .SetAccessModifier(AccessModifier.Public)
                                         .SetReturnType(descriptor.RuntimeType.Name)
                                         .AddParameter(_dataInfo, b => b.SetType(TypeNames.IOperationResultDataInfo))
                                         .AddParameter(
                _snapshot,
                b => b.SetDefault("null")
                .SetType(TypeNames.IEntityStoreSnapshot.MakeNullable()));

            if (settings.IsStoreEnabled())
            {
                createMethod
                .AddCode(
                    IfBuilder.New()
                    .SetCondition($"{_snapshot} is null")
                    .AddCode(
                        AssignmentBuilder
                        .New()
                        .SetLefthandSide(_snapshot)
                        .SetRighthandSide($"{_entityStore}.CurrentSnapshot")))
                .AddEmptyLine();
            }

            createMethod.AddCode(ifHasCorrectType)
            .AddEmptyLine()
            .AddCode(
                ExceptionBuilder
                .New(TypeNames.ArgumentException)
                .AddArgument(
                    $"\"{CreateResultInfoName(descriptor.RuntimeType.Name)} expected.\""));

            var processed = new HashSet <string>();

            AddRequiredMapMethods(
                settings,
                _info,
                descriptor,
                classBuilder,
                constructorBuilder,
                processed,
                true);

            classBuilder
            .AddProperty("ResultType")
            .SetType(TypeNames.Type)
            .AsLambda($"typeof({descriptor.RuntimeType.Namespace}.{descriptor.Implements[0]})")
            .SetInterface(TypeNames.IOperationResultDataFactory);

            classBuilder
            .AddMethod("Create")
            .SetInterface(TypeNames.IOperationResultDataFactory)
            .SetReturnType(TypeNames.Object)
            .AddParameter(_dataInfo, b => b.SetType(TypeNames.IOperationResultDataInfo))
            .AddParameter(
                _snapshot,
                b => b.SetType(TypeNames.IEntityStoreSnapshot.MakeNullable()))
            .AddCode(
                MethodCallBuilder
                .New()
                .SetReturn()
                .SetMethodName("Create")
                .AddArgument(_dataInfo)
                .AddArgument(_snapshot));

            classBuilder.Build(writer);
        }
        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));
        }