public async Task Class_With_Field_Constructor_Property_Method()
        {
            // arrange
            var sb     = new StringBuilder();
            var writer = new CodeWriter(sb);

            // act
            await ClassBuilder.New()
            .SetName("MyClass")
            .AddImplements("SomeOtherType")
            .SetAbstract()
            .AddField(FieldBuilder.New()
                      .SetName("_foo")
                      .SetType("Bar")
                      .SetReadOnly())
            .AddProperty(
                PropertyBuilder.New()
                .SetName("Foo")
                .SetType("Bar")
                .SetBackingField("_foo"))
            .AddConstructor(ConstructorBuilder.New()
                            .SetAccessModifier(AccessModifier.Protected)
                            .AddParameter(ParameterBuilder.New()
                                          .SetName("foo")
                                          .SetType("Bar")
                                          .SetDefault())
                            .AddCode("_foo = foo;"))
            .AddMethod(MethodBuilder.New()
                       .SetName("GetFooAsync")
                       .SetReturnType("ValueTask<Bar>")
                       .AddCode("return new ValueTask<Bar>(_foo);"))
            .BuildAsync(writer);

            // assert
            sb.ToString().MatchSnapshot();
        }
Beispiel #2
0
        protected override void Generate(
            CodeWriter writer,
            ITypeDescriptor typeDescriptor,
            out string fileName)
        {
            ComplexTypeDescriptor complexTypeDescriptor =
                typeDescriptor as ComplexTypeDescriptor ??
                throw new InvalidOperationException(
                          "A result entity mapper can only be generated for complex types");

            var(classBuilder, constructorBuilder) = CreateClassBuilder();

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

            fileName = className;

            classBuilder
            .AddImplements(TypeNames.IOperationResultDataInfo)
            .SetName(fileName);

            constructorBuilder
            .SetTypeName(complexTypeDescriptor.RuntimeType.Name)
            .SetAccessModifier(AccessModifier.Public);


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

                // Add Property to class
                classBuilder.AddProperty(
                    prop.Name,
                    x => x.SetType(propTypeBuilder).SetAccessModifier(AccessModifier.Public));

                // Add initialization of property to the constructor
                var paramName = GetParameterName(prop.Name);
                ParameterBuilder parameterBuilder = ParameterBuilder.New()
                                                    .SetName(paramName)
                                                    .SetType(propTypeBuilder);

                constructorBuilder.AddParameter(parameterBuilder);
                constructorBuilder.AddCode(prop.Name + " = " + paramName + ";");
            }

            classBuilder.AddProperty(
                "EntityIds",
                x => x.SetType(TypeNames.IReadOnlyCollection.WithGeneric(TypeNames.EntityId))
                .AsLambda("_entityIds"));

            classBuilder.AddProperty("Version", x => x.SetType("ulong").AsLambda("_version"));

            AddConstructorAssignedField(
                $"{TypeNames.IReadOnlyCollection}<{TypeNames.EntityId}>",
                "_entityIds",
                classBuilder,
                constructorBuilder);

            AddConstructorAssignedField(
                "ulong",
                "_version",
                classBuilder,
                constructorBuilder,
                true);


            // WithVersion

            classBuilder.AddMethod(
                "WithVersion",
                x => x.SetAccessModifier(AccessModifier.Public)
                .SetReturnType(TypeNames.IOperationResultDataInfo)
                .AddParameter(ParameterBuilder.New()
                              .SetType("ulong")
                              .SetName("version"))
                .AddCode(MethodCallBuilder.New()
                         .SetPrefix("return new ")
                         .SetMethodName(className)
                         .AddArgumentRange(
                             complexTypeDescriptor.Properties.Select(x => x.Name.Value))
                         .AddArgument("_entityIds")
                         .AddArgument("_version")));


            CodeFileBuilder
            .New()
            .SetNamespace(complexTypeDescriptor.RuntimeType.NamespaceWithoutGlobal)
            .AddType(classBuilder)
            .Build(writer);
        }
Beispiel #3
0
        protected override void Generate(
            CodeWriter writer,
            DataTypeDescriptor descriptor,
            out string fileName)
        {
            // Setup class
            fileName = descriptor.RuntimeType.Name;
            AbstractTypeBuilder typeBuilder;
            ConstructorBuilder? constructorBuilder = null;

            var typenamePropName = "__typename";

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

                typeBuilder.AddProperty(PropertyBuilder.New()
                                        .SetName(typenamePropName)
                                        .SetType(TypeNames.String));
            }
            else
            {
                var(classBuilder, constructorBuilder2) = CreateClassBuilder();
                constructorBuilder2
                .SetTypeName(fileName)
                .SetAccessModifier(AccessModifier.Public);

                constructorBuilder = constructorBuilder2;

                classBuilder.AddProperty(
                    PropertyBuilder
                    .New()
                    .SetAccessModifier(AccessModifier.Public)
                    .SetName(typenamePropName)
                    .SetType(TypeNames.String));

                var paramName  = "typename";
                var assignment = AssignmentBuilder
                                 .New()
                                 .SetLefthandSide(typenamePropName)
                                 .SetRighthandSide(paramName)
                                 .AssertNonNull();

                constructorBuilder.AddParameter(
                    ParameterBuilder
                    .New()
                    .SetType(TypeNames.String)
                    .SetName(paramName))
                .AddCode(assignment);

                classBuilder.SetName(fileName);
                typeBuilder = classBuilder;
            }

            // Add Properties to class
            foreach (PropertyDescriptor item in descriptor.Properties)
            {
                var itemParamName = GetParameterName(item.Name);
                var assignment    = AssignmentBuilder
                                    .New()
                                    .SetLefthandSide(item.Name)
                                    .SetRighthandSide(itemParamName);

                var paramType = item.Type.IsEntityType()
                    ? item.Type.ToEntityIdBuilder()
                    : item.Type.ToBuilder();
                constructorBuilder?.AddParameter(
                    ParameterBuilder
                    .New()
                    .SetType(paramType)
                    .SetName(itemParamName)
                    .SetDefault("null"))
                .AddCode(assignment);

                switch (item.Type.Kind)
                {
                case TypeKind.LeafType:
                    typeBuilder.AddProperty(item.Name)
                    .SetType(item.Type.ToBuilder())
                    .SetAccessModifier(AccessModifier.Public);
                    break;

                case TypeKind.DataType:
                    typeBuilder.AddProperty(item.Name)
                    // TODO this looks wrong. We should avoid nameoverride and delete it
                    .SetType(item.Type.ToBuilder(item.Type.Name))
                    .SetAccessModifier(AccessModifier.Public);
                    break;

                case TypeKind.EntityType:
                    typeBuilder.AddProperty(item.Name)
                    .SetType(item.Type.ToBuilder().SetName(TypeNames.EntityId))
                    .SetAccessModifier(AccessModifier.Public);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            foreach (NameString superType in descriptor.Implements)
            {
                typeBuilder.AddImplements(CreateDataTypeName(superType));
            }

            CodeFileBuilder
            .New()
            .SetNamespace(descriptor.RuntimeType.NamespaceWithoutGlobal)
            .AddType(typeBuilder)
            .Build(writer);
        }
        protected override void Generate(
            CodeWriter writer,
            ResultBuilderDescriptor resultBuilderDescriptor, out string fileName)
        {
            var processed            = new HashSet <string>();
            var resultTypeDescriptor = resultBuilderDescriptor.ResultNamedType;

            var(classBuilder, constructorBuilder) = CreateClassBuilder();

            fileName = resultBuilderDescriptor.Name;
            classBuilder.SetName(fileName);

            constructorBuilder.SetTypeName(fileName);

            classBuilder.AddImplements(
                $"{TypeNames.IOperationResultBuilder}<{TypeNames.JsonDocument}," +
                $" {resultTypeDescriptor.Name}>");

            AddConstructorAssignedField(
                TypeNames.IEntityStore,
                _entityStoreFieldName,
                classBuilder,
                constructorBuilder);

            AddConstructorAssignedField(
                TypeReferenceBuilder.New()
                .SetName(TypeNames.Func)
                .AddGeneric(TypeNames.JsonElement)
                .AddGeneric(TypeNames.EntityId),
                _extractIdFieldName,
                classBuilder,
                constructorBuilder);

            AddConstructorAssignedField(
                TypeReferenceBuilder.New()
                .SetName(TypeNames.IOperationResultDataFactory)
                .AddGeneric(resultTypeDescriptor.Name),
                _resultDataFactoryFieldName,
                classBuilder,
                constructorBuilder);

            constructorBuilder.AddParameter(
                ParameterBuilder.New()
                .SetName(_serializerResolverParamName)
                .SetType(TypeNames.ISerializerResolver));

            IEnumerable <ValueParserDescriptor> neededSerializers = resultBuilderDescriptor
                                                                    .ValueParsers
                                                                    .ToLookup(x => x.RuntimeType)
                                                                    .Select(x => x.First());

            foreach (ValueParserDescriptor valueParser in neededSerializers)
            {
                var parserFieldName =
                    $"_{valueParser.RuntimeType.Split('.').Last().WithLowerFirstChar()}Parser";
                classBuilder.AddField(
                    FieldBuilder.New().SetName(parserFieldName).SetType(
                        TypeReferenceBuilder.New()
                        .SetName(TypeNames.ILeafValueParser)
                        .AddGeneric(valueParser.SerializedType)
                        .AddGeneric(valueParser.RuntimeType)));

                constructorBuilder.AddCode(
                    AssignmentBuilder.New()
                    .AssertNonNull(parserFieldName)
                    .SetLefthandSide(parserFieldName)
                    .SetRighthandSide(
                        MethodCallBuilder.New()
                        .SetPrefix(_serializerResolverParamName + ".")
                        .SetDetermineStatement(false)
                        .SetMethodName(
                            $"GetLeafValueParser<{valueParser.SerializedType}, " +
                            $"{valueParser.RuntimeType}>")
                        .AddArgument($"\"{valueParser.GraphQLTypeName}\"")));
            }

            AddBuildMethod(
                resultTypeDescriptor,
                classBuilder);

            AddBuildDataMethod(
                resultTypeDescriptor,
                classBuilder);

            AddRequiredDeserializeMethods(
                resultBuilderDescriptor.ResultNamedType,
                classBuilder,
                processed);

            CodeFileBuilder.New()
            .SetNamespace(resultBuilderDescriptor.ResultNamedType.Namespace)
            .AddType(classBuilder)
            .Build(writer);
        }
Beispiel #5
0
        protected override void Generate(
            CodeWriter writer,
            ResultBuilderDescriptor resultBuilderDescriptor,
            out string fileName)
        {
            var processed            = new HashSet <string>();
            var resultTypeDescriptor =
                resultBuilderDescriptor.ResultNamedType as InterfaceTypeDescriptor
                ?? throw new InvalidOperationException(
                          "A result type can only be generated for complex types");

            var(classBuilder, constructorBuilder) = CreateClassBuilder();

            fileName = resultBuilderDescriptor.RuntimeType.Name;
            classBuilder.SetName(fileName);

            constructorBuilder.SetTypeName(fileName);

            classBuilder.AddImplements(
                $"{TypeNames.IOperationResultBuilder}<{TypeNames.JsonDocument}," +
                $" {resultTypeDescriptor.RuntimeType.Name}>");

            AddConstructorAssignedField(
                TypeNames.IEntityStore,
                _entityStoreFieldName,
                classBuilder,
                constructorBuilder);

            AddConstructorAssignedField(
                TypeReferenceBuilder.New()
                .SetName(TypeNames.Func)
                .AddGeneric(TypeNames.JsonElement)
                .AddGeneric(TypeNames.EntityId),
                _extractIdFieldName,
                classBuilder,
                constructorBuilder);

            AddConstructorAssignedField(
                TypeReferenceBuilder.New()
                .SetName(TypeNames.IOperationResultDataFactory)
                .AddGeneric(resultTypeDescriptor.RuntimeType.Name),
                _resultDataFactoryFieldName,
                classBuilder,
                constructorBuilder);

            constructorBuilder.AddParameter(
                ParameterBuilder.New()
                .SetName(_serializerResolverParamName)
                .SetType(TypeNames.ISerializerResolver));

            IEnumerable <ValueParserDescriptor> valueParsers = resultBuilderDescriptor
                                                               .ValueParsers
                                                               .GroupBy(t => t.Name)
                                                               .Select(t => t.First());

            foreach (ValueParserDescriptor valueParser in valueParsers)
            {
                var parserFieldName = $"{GetFieldName(valueParser.Name)}Parser";

                classBuilder.AddField(
                    FieldBuilder.New()
                    .SetReadOnly()
                    .SetName(parserFieldName)
                    .SetType(
                        TypeReferenceBuilder.New()
                        .SetName(TypeNames.ILeafValueParser)
                        .AddGeneric(valueParser.SerializedType.ToString())
                        .AddGeneric(valueParser.RuntimeType.ToString())));

                constructorBuilder.AddCode(
                    AssignmentBuilder.New()
                    .SetAssertNonNull()
                    .SetAssertException(
                        TypeNames.ArgumentException +
                        $"(\"No serializer for type `{valueParser.Name}` found.\")")
                    .SetLefthandSide(parserFieldName)
                    .SetRighthandSide(
                        MethodCallBuilder.New()
                        .SetPrefix(_serializerResolverParamName + ".")
                        .SetDetermineStatement(false)
                        .SetMethodName(
                            $"GetLeafValueParser<{valueParser.SerializedType}, " +
                            $"{valueParser.RuntimeType}>")
                        .AddArgument($"\"{valueParser.Name}\"")));
            }

            AddBuildMethod(
                resultTypeDescriptor,
                classBuilder);

            AddBuildDataMethod(
                resultTypeDescriptor,
                classBuilder);

            AddRequiredDeserializeMethods(
                resultBuilderDescriptor.ResultNamedType,
                classBuilder,
                processed);

            CodeFileBuilder.New()
            .SetNamespace(
                resultBuilderDescriptor.ResultNamedType.RuntimeType.NamespaceWithoutGlobal)
            .AddType(classBuilder)
            .Build(writer);
        }
        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);
        }
Beispiel #7
0
 public MethodBuilder AddParameter(ParameterBuilder value)
 {
     _parameters.Add(value);
     return(this);
 }
Beispiel #8
0
        protected override Task WriteAsync(
            CodeWriter writer,
            EnumValueSerializerDescriptor descriptor)
        {
            if (writer is null)
            {
                throw new ArgumentNullException(nameof(writer));
            }

            if (descriptor is null)
            {
                throw new ArgumentNullException(nameof(descriptor));
            }

            return(ClassBuilder.New()
                   .SetAccessModifier(AccessModifier.Public)
                   .SetSealed()
                   .SetName(descriptor.Name)
                   .AddImplements("global::StrawberryShake.IValueSerializer")
                   .AddProperty(PropertyBuilder.New()
                                .SetAccessModifier(AccessModifier.Public)
                                .SetType("string")
                                .SetName("Name")
                                .SetGetter(CodeLineBuilder.New()
                                           .SetLine($"return \"{descriptor.EnumGraphQLTypeName}\";")))
                   .AddProperty(PropertyBuilder.New()
                                .SetAccessModifier(AccessModifier.Public)
                                .SetType("global::StrawberryShake.ValueKind")
                                .SetName("Kind")
                                .SetGetter(CodeLineBuilder.New()
                                           .SetLine($"return global::StrawberryShake.ValueKind.Enum;")))
                   .AddProperty(PropertyBuilder.New()
                                .SetAccessModifier(AccessModifier.Public)
                                .SetType("global::System.Type")
                                .SetName("ClrType")
                                .SetGetter(CodeLineBuilder.New()
                                           .SetLine($"return typeof({descriptor.EnumTypeName});")))
                   .AddProperty(PropertyBuilder.New()
                                .SetAccessModifier(AccessModifier.Public)
                                .SetType("global::System.Type")
                                .SetName("SerializationType")
                                .SetGetter(CodeLineBuilder.New()
                                           .SetLine($"return typeof(string);")))
                   .AddMethod(MethodBuilder.New()
                              .SetAccessModifier(AccessModifier.Public)
                              .SetReturnType("object?", NullableRefTypes)
                              .SetReturnType("object", !NullableRefTypes)
                              .SetName("Serialize")
                              .AddParameter(ParameterBuilder.New()
                                            .SetType("object?", NullableRefTypes)
                                            .SetType("object", !NullableRefTypes)
                                            .SetName("value"))
                              .AddCode(CreateSerializerMethodBody(descriptor, CodeWriter.Indent)))
                   .AddMethod(MethodBuilder.New()
                              .SetAccessModifier(AccessModifier.Public)
                              .SetReturnType("object?", NullableRefTypes)
                              .SetReturnType("object", !NullableRefTypes)
                              .SetName("Deserialize")
                              .AddParameter(ParameterBuilder.New()
                                            .SetType("object?", NullableRefTypes)
                                            .SetType("object", !NullableRefTypes)
                                            .SetName("serialized"))
                              .AddCode(CreateDeserializerMethodBody(descriptor, CodeWriter.Indent)))
                   .BuildAsync(writer));
        }
Beispiel #9
0
        protected override void Generate(
            CodeWriter writer,
            ITypeDescriptor typeDescriptor,
            out string fileName)
        {
            var(classBuilder, constructorBuilder) = CreateClassBuilder(false);

            ComplexTypeDescriptor descriptor =
                typeDescriptor as ComplexTypeDescriptor ??
                throw new InvalidOperationException(
                          "A result entity mapper can only be generated for complex types");

            // Setup class
            fileName = descriptor.ExtractMapperName();

            classBuilder
            .AddImplements(
                TypeNames.IEntityMapper
                .WithGeneric(descriptor.ExtractTypeName(), descriptor.RuntimeType.Name))
            .SetName(fileName);

            constructorBuilder.SetTypeName(descriptor.Name);

            if (descriptor.ContainsEntity())
            {
                AddConstructorAssignedField(
                    TypeNames.IEntityStore,
                    StoreFieldName,
                    classBuilder,
                    constructorBuilder);
            }

            // Define map method
            MethodBuilder mapMethod = MethodBuilder.New()
                                      .SetName(_mapMethodName)
                                      .SetAccessModifier(AccessModifier.Public)
                                      .SetReturnType(descriptor.RuntimeType.Name)
                                      .AddParameter(
                ParameterBuilder.New()
                .SetType(
                    descriptor.Kind == TypeKind.EntityType
                                ? CreateEntityTypeName(descriptor.Name)
                                : descriptor.Name)
                .SetName(_entityParamName));

            var constructorCall =
                MethodCallBuilder
                .New()
                .SetMethodName($"return new {descriptor.RuntimeType.Name}");

            if (typeDescriptor is ComplexTypeDescriptor complexTypeDescriptor)
            {
                foreach (PropertyDescriptor property in complexTypeDescriptor.Properties)
                {
                    constructorCall.AddArgument(BuildMapMethodCall(_entityParamName, property));
                }
            }

            mapMethod.AddCode(constructorCall);

            if (constructorBuilder.HasParameters())
            {
                classBuilder.AddConstructor(constructorBuilder);
            }

            classBuilder.AddMethod(mapMethod);

            AddRequiredMapMethods(
                _entityParamName,
                descriptor,
                classBuilder,
                constructorBuilder,
                new HashSet <string>());

            CodeFileBuilder
            .New()
            .SetNamespace(descriptor.RuntimeType.NamespaceWithoutGlobal)
            .AddType(classBuilder)
            .Build(writer);
        }
        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);
            }
        }
 public ConstructorBuilder AddParameter(ParameterBuilder value)
 {
     _parameters.Add(value);
     return(this);
 }
        protected override void Generate(
            CodeWriter writer,
            ITypeDescriptor typeDescriptor,
            out string fileName)
        {
            var(classBuilder, constructorBuilder) = CreateClassBuilder(false);

            NamedTypeDescriptor descriptor = (NamedTypeDescriptor)typeDescriptor.NamedType();

            // Setup class
            fileName = descriptor.ExtractMapperName();

            classBuilder
            .AddImplements(
                TypeNames.IEntityMapper
                .WithGeneric(descriptor.ExtractTypeName(), descriptor.Name))
            .SetName(fileName);

            constructorBuilder.SetTypeName(descriptor.Name);

            if (descriptor.ContainsEntity())
            {
                AddConstructorAssignedField(
                    TypeNames.IEntityStore,
                    StoreFieldName,
                    classBuilder,
                    constructorBuilder);
            }

            // Define map method
            MethodBuilder mapMethod = MethodBuilder.New()
                                      .SetName(_mapMethodName)
                                      .SetAccessModifier(AccessModifier.Public)
                                      .SetReturnType(descriptor.Name)
                                      .AddParameter(
                ParameterBuilder.New()
                .SetType(
                    descriptor.Kind == TypeKind.EntityType
                                ? EntityTypeNameFromGraphQLTypeName(descriptor.GraphQLTypeName)
                                : descriptor.Name)
                .SetName(_entityParamName));

            var constructorCall =
                MethodCallBuilder
                .New()
                .SetMethodName($"return new {descriptor.Name}");

            if (typeDescriptor is NamedTypeDescriptor namedTypeDescriptor)
            {
                foreach (PropertyDescriptor property in namedTypeDescriptor.Properties)
                {
                    constructorCall.AddArgument(BuildMapMethodCall(_entityParamName, property));
                }
            }

            mapMethod.AddCode(constructorCall);

            if (constructorBuilder.HasParameters())
            {
                classBuilder.AddConstructor(constructorBuilder);
            }

            classBuilder.AddMethod(mapMethod);

            var processed = new HashSet <string>();

            AddRequiredMapMethods(
                _entityParamName,
                descriptor,
                classBuilder,
                constructorBuilder,
                processed);

            CodeFileBuilder
            .New()
            .SetNamespace(descriptor.Namespace)
            .AddType(classBuilder)
            .Build(writer);
        }
Beispiel #13
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);
        }