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);
        }
Ejemplo n.º 2
0
        public static MethodBuilder AddParameter(
            this MethodBuilder builder,
            string name,
            Action <ParameterBuilder> configure)
        {
            ParameterBuilder?parameterBuilder = ParameterBuilder.New().SetName(name);

            configure(parameterBuilder);
            builder.AddParameter(parameterBuilder);
            return(builder);
        }
        private void AddDeserializeMethod(
            ITypeDescriptor typeReference,
            ClassBuilder classBuilder,
            HashSet <string> processed)
        {
            string methodName = DeserializerMethodNameFromTypeName(typeReference);

            if (processed.Add(methodName))
            {
                MethodBuilder methodBuilder = classBuilder
                                              .AddMethod()
                                              .SetPrivate()
                                              .SetReturnType(typeReference.ToEntityIdBuilder())
                                              .SetName(methodName);

                methodBuilder
                .AddParameter(_obj)
                .SetType(TypeNames.JsonElement.MakeNullable());

                if (typeReference.IsEntityType() || typeReference.ContainsEntity())
                {
                    methodBuilder
                    .AddParameter(_entityIds)
                    .SetType(TypeNames.ISet.WithGeneric(TypeNames.EntityId));
                }

                IfBuilder jsonElementNullCheck = IfBuilder
                                                 .New()
                                                 .SetCondition($"!{_obj}.HasValue")
                                                 .AddCode(
                    typeReference.IsNonNullableType()
                            ? ExceptionBuilder.New(TypeNames.ArgumentNullException)
                            : CodeLineBuilder.From("return null;"));

                methodBuilder
                .AddCode(jsonElementNullCheck)
                .AddEmptyLine();

                AddDeserializeMethodBody(classBuilder, methodBuilder, typeReference, processed);
            }
        }
Ejemplo n.º 4
0
        public static ParameterBuilder AddParameter(
            this MethodBuilder builder,
            string?name = null)
        {
            ParameterBuilder parameterBuilder = ParameterBuilder.New();

            if (name is not null)
            {
                parameterBuilder.SetName(name);
            }

            builder.AddParameter(parameterBuilder);
            return(parameterBuilder);
        }
Ejemplo n.º 5
0
        private void AddEntityHandler(
            ClassBuilder classBuilder,
            ConstructorBuilder constructorBuilder,
            MethodBuilder method,
            ComplexTypeDescriptor complexTypeDescriptor,
            HashSet <string> processed,
            bool isNonNullable)
        {
            method.AddParameter(
                EntityIdParamName,
                x => x.SetType(TypeNames.EntityId.MakeNullable(!isNonNullable)));

            if (!isNonNullable)
            {
                method.AddCode(
                    EnsureProperNullability(
                        EntityIdParamName,
                        isNonNullable));
            }

            if (complexTypeDescriptor is InterfaceTypeDescriptor interfaceTypeDescriptor)
            {
                foreach (ObjectTypeDescriptor implementee in interfaceTypeDescriptor.ImplementedBy)
                {
                    NameString dataMapperName =
                        CreateEntityMapperName(
                            implementee.RuntimeType.Name,
                            implementee.Name);

                    if (processed.Add(dataMapperName))
                    {
                        var dataMapperType =
                            TypeNames.IEntityMapper.WithGeneric(
                                CreateEntityTypeName(implementee.Name),
                                implementee.RuntimeType.Name);

                        AddConstructorAssignedField(
                            dataMapperType,
                            GetFieldName(dataMapperName),
                            classBuilder,
                            constructorBuilder);
                    }

                    method.AddCode(GenerateEntityHandlerIfClause(implementee, isNonNullable));
                }
            }

            method.AddCode(ExceptionBuilder.New(TypeNames.NotSupportedException));
        }
Ejemplo n.º 6
0
        private void AddComplexDataHandler(
            ClassBuilder classBuilder,
            ConstructorBuilder constructorBuilder,
            MethodBuilder method,
            ComplexTypeDescriptor complexTypeDescriptor,
            HashSet <string> processed,
            bool isNonNullable)
        {
            if (complexTypeDescriptor.ParentRuntimeType is null)
            {
                throw new InvalidOperationException();
            }

            method.AddParameter(
                ParameterBuilder.New()
                .SetType(complexTypeDescriptor.ParentRuntimeType.ToString())
                .SetName(_dataParameterName));

            if (!isNonNullable)
            {
                method.AddCode(
                    EnsureProperNullability(
                        _dataParameterName,
                        isNonNullable));
            }

            var variableName = "returnValue";

            method.AddCode($"{complexTypeDescriptor.RuntimeType.Name} {variableName} = default!;");
            method.AddEmptyLine();

            GenerateIfForEachImplementedBy(
                method,
                complexTypeDescriptor,
                o => GenerateComplexDataInterfaceIfClause(o, variableName));

            method.AddCode($"return {variableName};");

            AddRequiredMapMethods(
                _dataParameterName,
                complexTypeDescriptor,
                classBuilder,
                constructorBuilder,
                processed);
        }
Ejemplo n.º 7
0
        private void AddDataHandler(
            ClassBuilder classBuilder,
            ConstructorBuilder constructorBuilder,
            MethodBuilder method,
            ComplexTypeDescriptor namedTypeDescriptor,
            HashSet <string> processed,
            bool isNonNullable)
        {
            method.AddParameter(
                _dataParameterName,
                x => x.SetType(namedTypeDescriptor.ParentRuntimeType !.ToString()));

            if (!isNonNullable)
            {
                method.AddCode(EnsureProperNullability(_dataParameterName, isNonNullable));
            }

            var variableName = "returnValue";

            method.AddCode($"{namedTypeDescriptor.RuntimeType.Name} {variableName} = default!;");
            method.AddEmptyLine();

            GenerateIfForEachImplementedBy(
                method,
                namedTypeDescriptor,
                o => GenerateDataInterfaceIfClause(o, isNonNullable, variableName));

            method.AddCode($"return {variableName};");

            AddRequiredMapMethods(
                _dataParameterName,
                namedTypeDescriptor,
                classBuilder,
                constructorBuilder,
                processed);
        }
        private void AddDataHandler(
            ClassBuilder classBuilder,
            ConstructorBuilder constructorBuilder,
            MethodBuilder method,
            NamedTypeDescriptor namedTypeDescriptor,
            HashSet <string> processed,
            bool isNonNullable)
        {
            method.AddParameter(
                ParameterBuilder.New()
                .SetType(
                    $"global::{namedTypeDescriptor.Namespace}.State." +
                    DataTypeNameFromTypeName(namedTypeDescriptor.GraphQLTypeName))
                .SetName(DataParamName));

            if (!isNonNullable)
            {
                method.AddCode(
                    EnsureProperNullability(
                        DataParamName,
                        isNonNullable));
            }

            var variableName = "returnValue";

            method.AddCode($"{namedTypeDescriptor.Name} {variableName} = default!;");
            method.AddEmptyLine();

            if (namedTypeDescriptor.ImplementedBy.Any())
            {
                var ifChain = InterfaceImplementeeIf(namedTypeDescriptor.ImplementedBy[0]);

                foreach (NamedTypeDescriptor interfaceImplementee in
                         namedTypeDescriptor.ImplementedBy.Skip(1))
                {
                    var singleIf = InterfaceImplementeeIf(interfaceImplementee).SkipIndents();
                    ifChain.AddIfElse(singleIf);
                }

                ifChain.AddElse(
                    CodeInlineBuilder.New()
                    .SetText($"throw new {TypeNames.NotSupportedException}();"));

                method.AddCode(ifChain);
            }

            IfBuilder InterfaceImplementeeIf(NamedTypeDescriptor interfaceImplementee)
            {
                var ifCorrectType = IfBuilder.New();

                if (isNonNullable)
                {
                    ifCorrectType.SetCondition(
                        $"{DataParamName}.__typename.Equals(\"" +
                        $"{interfaceImplementee.GraphQLTypeName}\", " +
                        $"{TypeNames.OrdinalStringComparisson})");
                }
                else
                {
                    ifCorrectType.SetCondition(
                        $"{DataParamName}?.__typename.Equals(\"" +
                        $"{interfaceImplementee.GraphQLTypeName}\", " +
                        $"{TypeNames.OrdinalStringComparisson}) ?? false");
                }


                var constructorCall = MethodCallBuilder.New()
                                      .SetPrefix($"{variableName} = new ")
                                      .SetMethodName(interfaceImplementee.Name);

                foreach (PropertyDescriptor prop in interfaceImplementee.Properties)
                {
                    var propAccess = $"{DataParamName}.{prop.Name}";
                    if (prop.Type.IsEntityType())
                    {
                        constructorCall.AddArgument(
                            BuildMapMethodCall(
                                DataParamName,
                                prop,
                                true));
                    }
                    else
                    {
                        constructorCall.AddArgument(
                            $"{propAccess} ?? throw new {TypeNames.ArgumentNullException}()");
                    }
                }

                ifCorrectType.AddCode(constructorCall);
                return(ifCorrectType);
            }

            method.AddCode($"return {variableName};");

            AddRequiredMapMethods(
                DataParamName,
                namedTypeDescriptor,
                classBuilder,
                constructorBuilder,
                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 AddEntityHandler(
            ClassBuilder classBuilder,
            ConstructorBuilder constructorBuilder,
            MethodBuilder method,
            NamedTypeDescriptor namedTypeDescriptor,
            HashSet <string> processed,
            bool isNonNullable)
        {
            var nullabilityAdditive = "?";

            if (isNonNullable)
            {
                nullabilityAdditive = "";
            }

            method.AddParameter(
                ParameterBuilder.New()
                .SetType(TypeNames.EntityId + nullabilityAdditive)
                .SetName(EntityIdParamName));

            if (!isNonNullable)
            {
                method.AddCode(
                    EnsureProperNullability(
                        EntityIdParamName,
                        isNonNullable));
            }


            foreach (NamedTypeDescriptor implementee in namedTypeDescriptor.ImplementedBy)
            {
                var dataMapperName =
                    EntityMapperNameFromGraphQLTypeName(
                        implementee.Name,
                        implementee.GraphQLTypeName);

                if (processed.Add(dataMapperName))
                {
                    var dataMapperType =
                        $"{TypeNames.IEntityMapper}<" +
                        $"{EntityTypeNameFromGraphQLTypeName(implementee.GraphQLTypeName)}, " +
                        $"{implementee.Name}>";

                    AddConstructorAssignedField(
                        dataMapperType,
                        dataMapperName.ToFieldName(),
                        classBuilder,
                        constructorBuilder);
                }
            }

            foreach (NamedTypeDescriptor interfaceImplementee in namedTypeDescriptor.ImplementedBy)
            {
                method.AddCode(InterfaceImplementeeIf(interfaceImplementee));
            }

            method.AddCode(ExceptionBuilder.New(TypeNames.NotSupportedException));

            IfBuilder InterfaceImplementeeIf(NamedTypeDescriptor interfaceImplementee)
            {
                var dataMapperName =
                    EntityMapperNameFromGraphQLTypeName(
                        interfaceImplementee.Name,
                        interfaceImplementee.GraphQLTypeName)
                    .ToFieldName();

                var ifCorrectType = IfBuilder.New();

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

                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(
                    EntityTypeNameFromGraphQLTypeName(interfaceImplementee.GraphQLTypeName))
                                             .AddArgument(isNonNullable ? EntityIdParamName : $"{EntityIdParamName}.Value");

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

                method.AddEmptyLine();
                ifCorrectType.AddCode(constructorCall);
                return(ifCorrectType);
            }
        }