Exemple #1
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);
        }
        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);
        }
Exemple #3
0
        protected override void Generate(
            CodeWriter writer,
            OperationDescriptor descriptor,
            out string fileName)
        {
            var(classBuilder, constructorBuilder) = CreateClassBuilder();

            fileName = DocumentTypeNameFromOperationName(descriptor.Name);
            classBuilder
            .AddImplements(TypeNames.IDocument)
            .SetName(fileName);
            constructorBuilder.SetAccessModifier(AccessModifier.Private);

            classBuilder.AddField(
                FieldBuilder.New()
                .SetStatic()
                .SetConst()
                .SetType(TypeNames.String)
                .SetName("_bodyString")
                .SetValue($"@\"{descriptor.BodyString}\"", true));

            classBuilder.AddField(
                FieldBuilder.New()
                .SetStatic()
                .SetReadOnly()
                .SetType("byte[]")
                .SetName("_body")
                .SetValue($"{TypeNames.EncodingUtf8}.GetBytes(_bodyString)"));

            string operationKind;

            switch (descriptor)
            {
            case MutationOperationDescriptor mutationOperationDescriptor:
                operationKind = "Mutation";
                break;

            case QueryOperationDescriptor queryOperationDescriptor:
                operationKind = "Query";
                break;

            case SubscriptionOperationDescriptor subscriptionOperationDescriptor:
                operationKind = "Subscription";
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(descriptor));
            }

            classBuilder.AddProperty(
                PropertyBuilder.New()
                .SetStatic()
                .SetType(fileName)
                .SetName("Instance")
                .SetValue($"new {fileName}()"));

            classBuilder.AddProperty(
                PropertyBuilder.New()
                .SetType(TypeNames.OperationKind)
                .SetName("Kind").AsLambda($"{TypeNames.OperationKind}.{operationKind}"));

            classBuilder.AddProperty(
                PropertyBuilder.New()
                .SetType($"{TypeNames.IReadOnlySpan}<byte>")
                .SetName("Body").AsLambda("_body"));

            classBuilder.AddMethod(
                MethodBuilder.New()
                .SetAccessModifier(AccessModifier.Public)
                .SetReturnType("override string")
                .SetName("ToString")
                .AddCode("return _bodyString;"));

            CodeFileBuilder
            .New()
            .SetNamespace(descriptor.Namespace)
            .AddType(classBuilder)
            .Build(writer);
        }
Exemple #4
0
 public ClassBuilder AddMethod(MethodBuilder method)
 {
     _methods.Add(method);
     return(this);
 }
Exemple #5
0
        private void AddDataTypeDeserializerMethod(
            ClassBuilder classBuilder,
            MethodBuilder methodBuilder,
            ComplexTypeDescriptor complexTypeDescriptor,
            HashSet <string> processed)
        {
            if (complexTypeDescriptor is InterfaceTypeDescriptor interfaceTypeDescriptor)
            {
                methodBuilder.AddCode(
                    "var typename = obj.Value.GetProperty(\"__typename\").GetString();");

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

                    var dataTypeName = $"{concreteType.RuntimeType.Namespace}.State."
                                       + CreateDataTypeName(concreteType.Name);

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

                    returnStatement.AddArgument("typename");
                    foreach (PropertyDescriptor property in concreteType.Properties)
                    {
                        returnStatement.AddArgument(
                            CodeBlockBuilder.New()
                            .AddCode($"{GetParameterName(property.Name)}: ")
                            .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(complexTypeDescriptor.Name);

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

                methodBuilder.AddCode(returnStatement);
            }

            AddRequiredDeserializeMethods(
                complexTypeDescriptor,
                classBuilder,
                processed);
        }
Exemple #6
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);
        }
Exemple #7
0
        protected override void Generate(
            CodeWriter writer,
            ITypeDescriptor typeDescriptor,
            out string fileName)
        {
            // Setup class
            ComplexTypeDescriptor descriptor =
                typeDescriptor as ComplexTypeDescriptor ??
                throw new InvalidOperationException(
                          "A result entity mapper can only be generated for complex types");

            fileName = descriptor.ExtractMapperName();

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

            ConstructorBuilder constructorBuilder = ConstructorBuilder
                                                    .New()
                                                    .SetTypeName(descriptor.Name);

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

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

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

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

            mapMethod.AddCode(constructorCall);

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

            classBuilder.AddMethod(mapMethod);

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

            CodeFileBuilder
            .New()
            .SetNamespace(descriptor.RuntimeType.NamespaceWithoutGlobal)
            .AddType(classBuilder)
            .Build(writer);
        }