public static CodeBlockBuilder AddBody(this ConstructorBuilder method)
        {
            var code = CodeBlockBuilder.New();

            method.AddCode(code);
            return(code);
        }
        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);
        }
        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, nameof(IEntityMapper <object, object> .Map));

            MethodCallBuilder argument = MethodCallBuilder
                                         .Inline()
                                         .SetMethodName(StoreFieldName, nameof(IEntityStore.GetEntity))
                                         .AddGeneric(CreateEntityTypeName(objectTypeDescriptor.Name))
                                         .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,
                nameof(EntityId.Name),
                nameof(string.Equals)
            }
                                : new[]
            {
                _entityId,
                nameof(Nullable <EntityId> .Value),
                nameof(EntityId.Name),
                nameof(string.Equals)
            })
                .AddArgument(objectTypeDescriptor.Name.AsStringToken())
                .AddArgument(TypeNames.OrdinalStringComparison));

            return(CodeBlockBuilder
                   .New()
                   .AddEmptyLine()
                   .AddCode(ifCorrectType));
        }
Esempio n. 4
0
        private void AddInterfaceDataTypeDeserializerToMethod(
            MethodBuilder methodBuilder,
            InterfaceTypeDescriptor interfaceTypeDescriptor)
        {
            methodBuilder.AddCode(
                AssignmentBuilder
                .New()
                .SetLefthandSide($"var {_typename}")
                .SetRighthandSide(MethodCallBuilder
                                  .Inline()
                                  .SetMethodName(
                                      _obj,
                                      nameof(Nullable <EntityId> .Value),
                                      nameof(JsonElement.GetProperty))
                                  .AddArgument(__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)
                {
                    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));
        }
Esempio n. 5
0
        private static ICode GenerateEntityHandlerIfClause(
            ObjectTypeDescriptor objectTypeDescriptor,
            bool isNonNullable)
        {
            var dataMapperName =
                GetFieldName(
                    CreateEntityMapperName(
                        objectTypeDescriptor.RuntimeType.Name,
                        objectTypeDescriptor.Name));

            var ifCorrectType = IfBuilder.New();

            if (isNonNullable)
            {
                ifCorrectType.SetCondition(
                    $"{EntityIdParamName}.Name.Equals(\"" +
                    $"{objectTypeDescriptor.Name}\", " +
                    $"{TypeNames.OrdinalStringComparison})");
            }
            else
            {
                ifCorrectType.SetCondition(
                    $"{EntityIdParamName}.Value.Name.Equals(\"" +
                    $"{objectTypeDescriptor.Name}\", " +
                    $"{TypeNames.OrdinalStringComparison})");
            }

            MethodCallBuilder constructorCall = MethodCallBuilder.New()
                                                .SetPrefix($"return {dataMapperName}.")
                                                .SetWrapArguments()
                                                .SetMethodName(nameof(IEntityMapper <object, object> .Map));

            MethodCallBuilder argument = MethodCallBuilder.New()
                                         .SetMethodName($"{StoreFieldName}.{nameof(IEntityStore.GetEntity)}")
                                         .SetDetermineStatement(false)
                                         .AddGeneric(CreateEntityTypeName(objectTypeDescriptor.Name))
                                         .AddArgument(isNonNullable ? EntityIdParamName : $"{EntityIdParamName}.Value");

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

            ifCorrectType.AddCode(constructorCall);

            return(CodeBlockBuilder.New()
                   .AddEmptyLine()
                   .AddCode(ifCorrectType));
        }
        public async Task CreateCodeBlock_With_CodeLineBuilder()
        {
            // arrange
            var sb     = new StringBuilder();
            var writer = new CodeWriter(sb);

            // act
            await CodeBlockBuilder.New()
            .AddCode("abc;")
            .AddCode(CodeLineBuilder.New().SetLine("def;"))
            .BuildAsync(writer);

            // assert
            sb.ToString().MatchSnapshot();
        }
Esempio n. 7
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};");
        private static CodeBlockBuilder CreateGetVariableValuesBody(
            IReadOnlyList <OperationArgumentDescriptor> arguments,
            string indent)
        {
            if (arguments.Count == 0)
            {
                return(CodeBlockBuilder.New()
                       .AddCode(
                           "return global::System.Array.Empty<" +
                           "global::StrawberryShake.VariableValue>();"));
            }

            var body = new StringBuilder();

            body.AppendLine("var variables = new List<VariableValue>();");
            body.AppendLine();

            foreach (OperationArgumentDescriptor argument in arguments)
            {
                if (argument.IsOptional)
                {
                    body.AppendLine("if (Episode.HasValue)");
                    body.AppendLine("{");
                    body.AppendLine(
                        $"{indent}variables.Add(new VariableValue(" +
                        $"\"{argument.GraphQLName}\", " +
                        $"\"{argument.GraphQLType}\", " +
                        $"{argument.Name}.Value));");
                    body.AppendLine("}");
                }
                else
                {
                    body.AppendLine(
                        $"variables.Add(new VariableValue(" +
                        $"\"{argument.GraphQLName}\", " +
                        $"\"{argument.GraphQLType}\", " +
                        $"{argument.Name}));");
                }
                body.AppendLine();
            }

            body.Append("return variables;");

            return(CodeBlockBuilder.FromStringBuilder(body));
        }
Esempio n. 9
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
                        .ToEntityIdBuilder()
                        .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);
        }
        private CodeBlockBuilder EnsureProperNullability(
            string propertyName = _objParamName,
            bool isNonNullType  = false)
        {
            var ifBuilder = IfBuilder
                            .New()
                            .SetCondition(
                ConditionBuilder.New()
                .Set($"!{propertyName}.HasValue"));

            ifBuilder.AddCode(
                isNonNullType
                    ? $"throw new {TypeNames.ArgumentNullException}();"
                    : "return null;");

            var codeBuilder = CodeBlockBuilder.New()
                              .AddCode(ifBuilder)
                              .AddEmptyLine();

            return(codeBuilder);
        }
Esempio n. 11
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);
        }
        private ICode CreateEntityIdBody(EntityIdFactoryDescriptor descriptor)
        {
            AssignmentBuilder typeNameAssigment =
                AssignmentBuilder
                    .New()
                    .SetLefthandSide($"{TypeNames.String} {_typeName}")
                    .SetRighthandSide(
                        MethodCallBuilder
                            .Inline()
                            .SetMethodName(_obj, nameof(JsonElement.GetProperty))
                            .AddArgument(__typename.AsStringToken())
                            .Chain(x => x
                                .SetMethodName(nameof(JsonElement.GetString))
                                .SetNullForgiving()));

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

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

            return CodeBlockBuilder
                .New()
                .AddCode(typeNameAssigment)
                .AddEmptyLine()
                .AddCode(typeNameSwitch);
        }
Esempio n. 13
0
        private static MethodBuilder BuildObjectEqualsMethod(string typeName)
        {
            const string obj = nameof(obj);

            return(MethodBuilder
                   .New()
                   .SetName(nameof(IEquatable <object> .Equals))
                   .SetPublic()
                   .SetOverride()
                   .SetReturnType(TypeNames.Boolean)
                   .AddParameter(obj, x => x.SetType(TypeNames.Object.MakeNullable()))
                   .AddCode(CodeBlockBuilder
                            .New()
                            .AddCode(IfBuilder
                                     .New()
                                     .SetCondition(MethodCallBuilder
                                                   .Inline()
                                                   .SetMethodName(nameof(ReferenceEquals))
                                                   .AddArgument("null")
                                                   .AddArgument(obj))
                                     .AddCode("return false;"))
                            .AddEmptyLine()
                            .AddCode(IfBuilder
                                     .New()
                                     .SetCondition(MethodCallBuilder
                                                   .Inline()
                                                   .SetMethodName(nameof(ReferenceEquals))
                                                   .AddArgument("this")
                                                   .AddArgument(obj))
                                     .AddCode("return true;"))
                            .AddEmptyLine()
                            .AddCode(IfBuilder
                                     .New()
                                     .SetCondition($"{obj}.GetType() != GetType()")
                                     .AddCode("return false;"))
                            .AddEmptyLine()
                            .AddLine($"return Equals(({typeName}){obj});")));
        }
 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;");
Esempio n. 15
0
        private void AddUpdateEntityMethod(
            ClassBuilder classBuilder,
            MethodBuilder methodBuilder,
            INamedTypeDescriptor namedTypeDescriptor,
            HashSet <string> processed)
        {
            var entityIdVarName = "entityId";

            methodBuilder.AddCode(
                AssignmentBuilder.New()
                .SetLefthandSide(
                    CodeBlockBuilder.New()
                    .AddCode(TypeNames.EntityId)
                    .AddCode($" {entityIdVarName}"))
                .SetRighthandSide($"{_extractIdFieldName}({_objParamName}.Value)"));

            methodBuilder.AddCode($"{_entityIdsParam}.Add({entityIdVarName});");
            methodBuilder.AddEmptyLine();

            var entityVarName = "entity";

            if (namedTypeDescriptor is InterfaceTypeDescriptor interfaceTypeDescriptor)
            {
                // If the type is an interface
                foreach (ObjectTypeDescriptor concreteType in interfaceTypeDescriptor.ImplementedBy)
                {
                    methodBuilder.AddEmptyLine();
                    var ifStatement = IfBuilder.New()
                                      .SetCondition(
                        $"entityId.Name.Equals(\"{concreteType.Name}\", " +
                        $"{TypeNames.OrdinalStringComparison})");

                    var entityTypeName = CreateEntityTypeName(concreteType.Name);

                    WriteEntityLoader(
                        ifStatement,
                        entityTypeName,
                        entityVarName,
                        entityIdVarName);

                    WritePropertyAssignments(
                        ifStatement,
                        concreteType.Properties,
                        entityVarName);

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

                methodBuilder.AddEmptyLine();
                methodBuilder.AddCode($"throw new {TypeNames.NotSupportedException}();");
            }
            else if (namedTypeDescriptor is ComplexTypeDescriptor complexTypeDescriptor)
            {
                WriteEntityLoader(
                    methodBuilder,
                    CreateEntityTypeName(namedTypeDescriptor.Name),
                    entityVarName,
                    entityIdVarName);

                WritePropertyAssignments(
                    methodBuilder,
                    complexTypeDescriptor.Properties,
                    entityVarName);

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

            AddRequiredDeserializeMethods(
                namedTypeDescriptor,
                classBuilder,
                processed);
        }
Esempio n. 16
0
        private void AddBuildDataMethod(
            NamedTypeDescriptor resultNamedType,
            ClassBuilder classBuilder)
        {
            var objParameter    = "obj";
            var buildDataMethod = MethodBuilder.New()
                                  .SetAccessModifier(AccessModifier.Private)
                                  .SetName("BuildData")
                                  .SetReturnType(
                $"({resultNamedType.Name}, " +
                $"{ResultInfoNameFromTypeName(resultNamedType.ImplementedBy[0].Name)})")
                                  .AddParameter(
                ParameterBuilder.New()
                .SetType(TypeNames.JsonElement)
                .SetName(objParameter));

            var sessionName = "session";

            buildDataMethod.AddCode(
                CodeLineBuilder.New()
                .SetLine(
                    CodeBlockBuilder.New()
                    .AddCode(
                        $"using {TypeNames.IEntityUpdateSession} {sessionName} = ")
                    .AddCode(_entityStoreFieldName + ".BeginUpdate();")));

            var entityIdsName = "entityIds";

            buildDataMethod.AddCode(
                CodeLineBuilder.New()
                .SetLine(
                    $"var {entityIdsName} = new {TypeNames.HashSet}<{TypeNames.EntityId}>();"));

            buildDataMethod.AddEmptyLine();
            foreach (PropertyDescriptor property in
                     resultNamedType.Properties.Where(prop => prop.Type.IsEntityType()))
            {
                buildDataMethod.AddCode(
                    AssignmentBuilder.New()
                    .SetLefthandSide(CodeBlockBuilder.New()
                                     .AddCode(property.Type.ToEntityIdBuilder())
                                     .AddCode($"{property.Name.WithLowerFirstChar()}Id"))
                    .SetRighthandSide(BuildUpdateMethodCall(property, "")));
            }

            var resultInfoConstructor = MethodCallBuilder.New()
                                        .SetMethodName(
                $"new {ResultInfoNameFromTypeName(resultNamedType.ImplementedBy[0].Name)}")
                                        .SetDetermineStatement(false);

            foreach (PropertyDescriptor property in resultNamedType.Properties)
            {
                if (property.Type.IsEntityType())
                {
                    resultInfoConstructor.AddArgument($"{property.Name.WithLowerFirstChar()}Id");
                }
                else
                {
                    resultInfoConstructor.AddArgument(BuildUpdateMethodCall(property, ""));
                }
            }

            resultInfoConstructor.AddArgument(entityIdsName);
            resultInfoConstructor.AddArgument(
                $"{sessionName}.{TypeNames.IEntityUpdateSession_Version}");

            buildDataMethod.AddEmptyLine();
            var resultInfoName = "resultInfo";

            buildDataMethod.AddCode(
                AssignmentBuilder.New()
                .SetLefthandSide($"var {resultInfoName}")
                .SetRighthandSide(resultInfoConstructor));

            buildDataMethod.AddEmptyLine();
            buildDataMethod.AddCode(
                $"return ({_resultDataFactoryFieldName}" +
                $".Create({resultInfoName}), {resultInfoName});");

            classBuilder.AddMethod(buildDataMethod);
        }
Esempio n. 17
0
        private void AddDataTypeDeserializerMethod(
            ClassBuilder classBuilder,
            MethodBuilder methodBuilder,
            NamedTypeDescriptor namedTypeDescriptor,
            HashSet <string> processed)
        {
            if (namedTypeDescriptor.IsInterface)
            {
                methodBuilder.AddCode(
                    "var typename = obj.Value.GetProperty(\"__typename\").GetString();");

                // If the type is an interface
                foreach (NamedTypeDescriptor concreteType in namedTypeDescriptor.ImplementedBy)
                {
                    methodBuilder.AddEmptyLine();
                    var ifStatement = IfBuilder.New()
                                      .SetCondition(
                        $"typename?.Equals(\"{concreteType.GraphQLTypeName}\", " +
                        $"{TypeNames.OrdinalStringComparisson}) ?? false");

                    var dataTypeName = $"global::{concreteType.Namespace}.State."
                                       + DataTypeNameFromTypeName(concreteType.GraphQLTypeName);

                    var returnStatement = MethodCallBuilder.New()
                                          .SetPrefix("return new ")
                                          .SetMethodName(dataTypeName);

                    returnStatement.AddArgument("typename");
                    foreach (PropertyDescriptor property in concreteType.Properties)
                    {
                        returnStatement.AddArgument(
                            CodeBlockBuilder.New()
                            .AddCode($"{property.Name.WithLowerFirstChar()}: ")
                            .AddCode(BuildUpdateMethodCall(property)));
                    }

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

                methodBuilder.AddEmptyLine();
                methodBuilder.AddCode($"throw new {TypeNames.NotSupportedException}();");
            }
            else
            {
                var returnStatement = MethodCallBuilder.New()
                                      .SetPrefix("return new ")
                                      .SetMethodName(namedTypeDescriptor.Name);

                foreach (PropertyDescriptor property in namedTypeDescriptor.Properties)
                {
                    returnStatement.AddArgument(BuildUpdateMethodCall(property));
                }

                methodBuilder.AddCode(returnStatement);
            }

            AddRequiredDeserializeMethods(
                namedTypeDescriptor,
                classBuilder,
                processed);
        }
        private void AddArrayHandler(
            ClassBuilder classBuilder,
            ConstructorBuilder constructorBuilder,
            MethodBuilder methodBuilder,
            ListTypeDescriptor listTypeDescriptor,
            HashSet <string> processed,
            bool isNonNullable)
        {
            methodBuilder
            .AddParameter(_list)
            .SetType(listTypeDescriptor.ToEntityIdBuilder());

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

            if (!isNonNullable)
            {
                methodBuilder.AddCode(EnsureProperNullability(_list, 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();

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

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

            AddMapMethod(
                listVarName,
                listTypeDescriptor.InnerType,
                classBuilder,
                constructorBuilder,
                processed);
        }
        private void AddBuildDataMethod(
            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))
                                            .AddCode(
                AssignmentBuilder
                .New()
                .SetLefthandSide($"using {TypeNames.IEntityUpdateSession} {_session}")
                .SetRighthandSide(
                    MethodCallBuilder
                    .Inline()
                    .SetMethodName(_entityStore, nameof(IEntityStore.BeginUpdate))))
                                            .AddCode(
                AssignmentBuilder
                .New()
                .SetLefthandSide($"var {_entityIds}")
                .SetRighthandSide(MethodCallBuilder
                                  .Inline()
                                  .SetNew()
                                  .SetMethodName(TypeNames.HashSet)
                                  .AddGeneric(TypeNames.EntityId)))
                                            .AddEmptyLine();

            foreach (PropertyDescriptor property in
                     resultNamedType.Properties.Where(prop => prop.Type.IsEntityType()))
            {
                buildDataMethod.AddCode(
                    AssignmentBuilder
                    .New()
                    .SetLefthandSide(CodeBlockBuilder
                                     .New()
                                     .AddCode(property.Type.ToEntityIdBuilder())
                                     .AddCode($"{GetParameterName(property.Name)}Id"))
                    .SetRighthandSide(BuildUpdateMethodCall(property)));
            }

            buildDataMethod
            .AddEmptyLine()
            .AddCode(
                AssignmentBuilder
                .New()
                .SetLefthandSide($"var {_resultInfo}")
                .SetRighthandSide(
                    CreateResultInfoMethodCall(resultNamedType, concreteType)))
            .AddEmptyLine()
            .AddCode(
                TupleBuilder
                .Inline()
                .SetDetermineStatement(true)
                .SetReturn()
                .AddMember(MethodCallBuilder
                           .Inline()
                           .SetMethodName(
                               _resultDataFactory,
                               nameof(IOperationResultDataFactory <object> .Create))
                           .AddArgument(_resultInfo))
                .AddMember(_resultInfo));
        }
        public static ClassBuilder AddEquality(
            this ClassBuilder builder,
            string typeName,
            IReadOnlyList <PropertyDescriptor> properties)
        {
            const string obj   = nameof(obj);
            const string other = nameof(other);

            builder.AddImplements(TypeNames.IEquatable.WithGeneric(typeName));

            builder
            .AddMethod(nameof(IEquatable <object> .Equals))
            .SetPublic()
            .SetOverride()
            .SetReturnType(TypeNames.Boolean)
            .AddParameter(obj, x => x.SetType(TypeNames.Object.MakeNullable()))
            .AddCode(CodeBlockBuilder
                     .New()
                     .AddCode(IfBuilder
                              .New()
                              .SetCondition(MethodCallBuilder
                                            .Inline()
                                            .SetMethodName(nameof(ReferenceEquals))
                                            .AddArgument("null")
                                            .AddArgument(obj))
                              .AddCode("return false;"))
                     .AddEmptyLine()
                     .AddCode(IfBuilder
                              .New()
                              .SetCondition(MethodCallBuilder
                                            .Inline()
                                            .SetMethodName(nameof(ReferenceEquals))
                                            .AddArgument("this")
                                            .AddArgument(obj))
                              .AddCode("return true;"))
                     .AddEmptyLine()
                     .AddCode(IfBuilder
                              .New()
                              .SetCondition($"{obj}.GetType() != GetType()")
                              .AddCode("return false;"))
                     .AddEmptyLine()
                     .AddLine($"return Equals(({typeName}){obj});"));

            ConditionBuilder equalCondition =
                ConditionBuilder
                .New()
                .SetReturn()
                .SetDetermineStatement();

            if (properties.Count == 0)
            {
                equalCondition.And("true");
            }
            else
            {
                foreach (PropertyDescriptor property in properties)
                {
                    equalCondition.And(ConditionBuilder
                                       .New()
                                       .Set(BuildPropertyComparison(property.Type, property.Name)));
                }
            }

            builder
            .AddMethod(nameof(IEquatable <object> .Equals))
            .SetPublic()
            .SetReturnType(TypeNames.Boolean)
            .AddParameter(other, x => x.SetType(typeName.MakeNullable()))
            .AddCode(CodeBlockBuilder
                     .New()
                     .AddCode(IfBuilder
                              .New()
                              .SetCondition(MethodCallBuilder
                                            .Inline()
                                            .SetMethodName(nameof(ReferenceEquals))
                                            .AddArgument("null")
                                            .AddArgument(other))
                              .AddCode("return false;"))
                     .AddEmptyLine()
                     .AddCode(IfBuilder
                              .New()
                              .SetCondition(MethodCallBuilder
                                            .Inline()
                                            .SetMethodName(nameof(ReferenceEquals))
                                            .AddArgument("this")
                                            .AddArgument(other))
                              .AddCode("return true;"))
                     .AddEmptyLine()
                     .AddCode(IfBuilder
                              .New()
                              .SetCondition($"{other}.GetType() != GetType()")
                              .AddCode("return false;"))
                     .AddEmptyLine()
                     .AddCode(equalCondition));

            builder
            .AddMethod(nameof(GetHashCode))
            .SetPublic()
            .SetOverride()
            .SetReturnType(TypeNames.Int32)
            .AddCode(HashCodeBuilder
                     .New()
                     .AddProperties(properties));

            return(builder);
        }
Esempio n. 21
0
        private ICode GenerateInternalMethodBody(DependencyInjectionDescriptor descriptor)
        {
            bool hasSubscriptions =
                descriptor.Operations.OfType <SubscriptionOperationDescriptor>().Any();
            bool hasQueries =
                descriptor.Operations.OfType <QueryOperationDescriptor>().Any();
            bool hasMutations =
                descriptor.Operations.OfType <MutationOperationDescriptor>().Any();

            var body = CodeBlockBuilder
                       .New()
                       .AddCode(_staticCode);

            if (hasSubscriptions)
            {
                body.AddCode(RegisterWebSocketConnection(descriptor.Name));
            }

            if (hasQueries || hasMutations)
            {
                body.AddCode(RegisterHttpConnection(descriptor.Name));
            }

            body.AddEmptyLine();

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

                    var interfaceName =
                        TypeNames.IEntityMapper.WithGeneric(
                            namedTypeDescriptor.ExtractTypeName(),
                            typeDescriptor.RuntimeType.Name);

                    body.AddMethodCall()
                    .SetMethodName(TypeNames.AddSingleton)
                    .AddGeneric(interfaceName)
                    .AddGeneric(className)
                    .AddArgument(_services);
                }
            }

            body.AddEmptyLine();

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

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

            RuntimeTypeInfo stringTypeInfo = TypeInfos.From(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.InputType))
            {
                body.AddMethodCall()
                .SetMethodName(TypeNames.AddSingleton)
                .AddGeneric(TypeNames.ISerializer)
                .AddGeneric(CreateInputValueFormatter(
                                (InputObjectTypeDescriptor)inputTypeDescriptor.NamedType()))
                .AddArgument(_services);
            }

            body.AddCode(RegisterSerializerResolver());

            body.AddEmptyLine();

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

                string connectionKind = operation is SubscriptionOperationDescriptor
                    ? TypeNames.WebSocketConnection
                    : TypeNames.HttpConnection;
                NameString operationName      = operation.OperationName;
                NameString fullName           = operation.Name;
                NameString operationInterface = typeDescriptor.RuntimeType.Name;

                // 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(
                        connectionKind,
                        fullName,
                        operationInterface,
                        factoryName,
                        builderName));
            }

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

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

            return(body);
        }
Esempio n. 22
0
 private static ICode RegisterOperation(
     string connectionKind,
     string fullName,
     string operationInterface,
     string factory,
     string resultBuilder)
 {
     return(CodeBlockBuilder
            .New()
            .AddCode(
                MethodCallBuilder
                .New()
                .SetMethodName(TypeNames.AddSingleton)
                .AddGeneric(
                    TypeNames.IOperationResultDataFactory.WithGeneric(operationInterface))
                .AddGeneric(factory)
                .AddArgument(_services))
            .AddCode(MethodCallBuilder
                     .New()
                     .SetMethodName(TypeNames.AddSingleton)
                     .AddGeneric(
                         TypeNames.IOperationResultBuilder
                         .WithGeneric(TypeNames.JsonDocument, operationInterface))
                     .AddGeneric(resultBuilder)
                     .AddArgument(_services))
            .AddCode(
                MethodCallBuilder
                .New()
                .SetMethodName(TypeNames.AddSingleton)
                .AddGeneric(TypeNames.IOperationExecutor.WithGeneric(operationInterface))
                .AddArgument(_services)
                .AddArgument(LambdaBuilder
                             .New()
                             .AddArgument(_sp)
                             .SetCode(MethodCallBuilder
                                      .Inline()
                                      .SetNew()
                                      .SetMethodName(TypeNames.OperationExecutor)
                                      .AddGeneric(TypeNames.JsonDocument)
                                      .AddGeneric(operationInterface)
                                      .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,
                                                      operationInterface))
                                              .AddArgument(_sp)))
                                      .AddArgument(
                                          MethodCallBuilder
                                          .Inline()
                                          .SetMethodName(TypeNames.GetRequiredService)
                                          .AddGeneric(TypeNames.IOperationStore)
                                          .AddArgument(_sp))
                                      .AddArgument(_strategy))))
            .AddCode(MethodCallBuilder
                     .New()
                     .SetMethodName(TypeNames.AddSingleton)
                     .AddGeneric(fullName)
                     .AddArgument(_services)));
 }