private ICode CreateEntityConstructorCall(
            ObjectTypeDescriptor objectTypeDescriptor,
            bool assignDefault)
        {
            var propertyLookup = objectTypeDescriptor.Properties.ToDictionary(x => x.Name.Value);

            MethodCallBuilder newEntity = MethodCallBuilder
                                          .Inline()
                                          .SetNew()
                                          .SetMethodName(objectTypeDescriptor.EntityTypeDescriptor.RuntimeType.ToString());

            foreach (PropertyDescriptor property in
                     objectTypeDescriptor.EntityTypeDescriptor.Properties.Values)
            {
                if (propertyLookup.TryGetValue(property.Name.Value, out var ownProperty))
                {
                    newEntity.AddArgument(BuildUpdateMethodCall(ownProperty));
                }
                else if (assignDefault)
                {
                    newEntity.AddArgument("default!");
                }
                else
                {
                    newEntity.AddArgument($"{_entity}.{property.Name}");
                }
            }

            return(MethodCallBuilder
                   .New()
                   .SetMethodName(_session, "SetEntity")
                   .AddArgument(_entityId)
                   .AddArgument(newEntity));
        }
        private MethodCallBuilder CreateResultInfoMethodCall(
            CSharpSyntaxGeneratorSettings settings,
            InterfaceTypeDescriptor resultNamedType,
            string concreteType)
        {
            MethodCallBuilder resultInfoConstructor = MethodCallBuilder
                                                      .Inline()
                                                      .SetMethodName($"new {concreteType}");

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

            if (settings.IsStoreEnabled())
            {
                resultInfoConstructor
                .AddArgument(_entityIds)
                .AddArgument($"{_snapshot}.Version");
            }

            return(resultInfoConstructor);
        }
Beispiel #3
0
        private IfBuilder GenerateDataInterfaceIfClause(
            ObjectTypeDescriptor objectTypeDescriptor,
            bool isNonNullable,
            string variableName)
        {
            ICode ifCondition = MethodCallBuilder
                                .Inline()
                                .SetMethodName(
                _dataParameterName.MakeNullable(!isNonNullable),
                WellKnownNames.TypeName,
                nameof(string.Equals))
                                .AddArgument(objectTypeDescriptor.Name.AsStringToken())
                                .AddArgument(TypeNames.OrdinalStringComparison);

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

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

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

            return(IfBuilder
                   .New()
                   .SetCondition(ifCondition)
                   .AddCode(AssignmentBuilder
                            .New()
                            .SetLefthandSide(variableName)
                            .SetRighthandSide(constructorCall)));
        }
        private IfBuilder GenerateComplexDataInterfaceIfClause(
            ObjectTypeDescriptor objectTypeDescriptor,
            string variableName)
        {
            var matchedTypeName = GetParameterName(objectTypeDescriptor.Name);

            // since we want to create the data name we will need to craft the type name
            // by hand by using the GraphQL type name and the state namespace.
            var dataTypeName = new RuntimeTypeInfo(
                CreateDataTypeName(objectTypeDescriptor.Name),
                $"{objectTypeDescriptor.RuntimeType.Namespace}.State");

            var block = CodeBlockBuilder.New();

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

            foreach (PropertyDescriptor prop in objectTypeDescriptor.Properties)
            {
                if (prop.Type.IsEntityType())
                {
                    constructorCall.AddArgument(BuildMapMethodCall(matchedTypeName, prop));
                }
                else if (prop.Type.IsNonNullableType())
                {
                    if (prop.Type.NamedType() is ILeafTypeDescriptor
                    {
                        RuntimeType: { IsValueType: true }
                    })
Beispiel #5
0
        private MethodCallBuilder CreateBuildDataStatement(ObjectTypeDescriptor concreteType)
        {
            MethodCallBuilder returnStatement = MethodCallBuilder
                                                .New()
                                                .SetNew()
                                                .SetMethodName(
                $"{concreteType.RuntimeType.Namespace}.State." +
                CreateDataTypeName(concreteType.Name))
                                                .AddArgument("typename");

            foreach (PropertyDescriptor property in concreteType.Properties)
            {
                if (property.Name.Value.EqualsOrdinal(WellKnownNames.TypeName))
                {
                    continue;
                }

                returnStatement.AddArgument(
                    CodeBlockBuilder
                    .New()
                    .AddCode($"{GetParameterName(property.Name)}: ")
                    .AddCode(BuildUpdateMethodCall(property)));
            }

            return(returnStatement);
        }
        private void AddDataTypeDeserializerMethod(
            ClassBuilder classBuilder,
            MethodBuilder methodBuilder,
            ComplexTypeDescriptor complexTypeDescriptor,
            HashSet <string> processed)
        {
            if (complexTypeDescriptor is InterfaceTypeDescriptor interfaceTypeDescriptor)
            {
                AddInterfaceDataTypeDeserializerToMethod(methodBuilder, interfaceTypeDescriptor);
            }
            else
            {
                MethodCallBuilder returnStatement = MethodCallBuilder
                                                    .New()
                                                    .SetReturn()
                                                    .SetNew()
                                                    .SetMethodName(complexTypeDescriptor.Name);

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

                methodBuilder.AddCode(returnStatement);
            }

            AddRequiredDeserializeMethods(complexTypeDescriptor, classBuilder, processed);
        }
        private void AddInterfaceDataTypeDeserializerToMethod(
            MethodBuilder methodBuilder,
            InterfaceTypeDescriptor interfaceTypeDescriptor)
        {
            methodBuilder.AddCode(
                AssignmentBuilder
                .New()
                .SetLefthandSide($"var {_typename}")
                .SetRighthandSide(MethodCallBuilder
                                  .Inline()
                                  .SetMethodName(
                                      _obj,
                                      "Value",
                                      nameof(JsonElement.GetProperty))
                                  .AddArgument(WellKnownNames.TypeName.AsStringToken())
                                  .Chain(x => x.SetMethodName(nameof(JsonElement.GetString)))));

            // If the type is an interface
            foreach (ObjectTypeDescriptor concreteType in interfaceTypeDescriptor.ImplementedBy)
            {
                MethodCallBuilder returnStatement = MethodCallBuilder
                                                    .New()
                                                    .SetReturn()
                                                    .SetNew()
                                                    .SetMethodName(
                    $"{concreteType.RuntimeType.Namespace}.State." +
                    CreateDataTypeName(concreteType.Name))
                                                    .AddArgument("typename");

                foreach (PropertyDescriptor property in concreteType.Properties)
                {
                    if (property.Name.Value.EqualsOrdinal(WellKnownNames.TypeName))
                    {
                        continue;
                    }

                    returnStatement.AddArgument(
                        CodeBlockBuilder
                        .New()
                        .AddCode($"{GetParameterName(property.Name)}: ")
                        .AddCode(BuildUpdateMethodCall(property)));
                }

                IfBuilder ifStatement = IfBuilder
                                        .New()
                                        .SetCondition(
                    $"typename?.Equals(\"{concreteType.Name}\", " +
                    $"{TypeNames.OrdinalStringComparison}) ?? false")
                                        .AddCode(returnStatement);

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

            methodBuilder
            .AddEmptyLine()
            .AddCode(ExceptionBuilder.New(TypeNames.NotSupportedException));
        }
        private 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));
        }
        private MethodCallBuilder BuildUpdateMethodCall(
            ITypeDescriptor property,
            ICode argument)
        {
            MethodCallBuilder deserializeMethodCaller = MethodCallBuilder
                                                        .Inline()
                                                        .SetMethodName(DeserializerMethodNameFromTypeName(property));

            deserializeMethodCaller.AddArgument(argument);

            if (property.IsEntityType() || property.ContainsEntity())
            {
                deserializeMethodCaller.AddArgument(_entityIds);
            }

            return(deserializeMethodCaller);
        }
        public static MethodCallBuilder AddArgumentRange(
            this MethodCallBuilder builder,
            IEnumerable <string> arguments)
        {
            foreach (var argument in arguments)
            {
                builder.AddArgument(argument);
            }

            return(builder);
        }
Beispiel #11
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));
        }
        private IfBuilder GenerateComplexDataInterfaceIfClause(
            ObjectTypeDescriptor objectTypeDescriptor,
            string variableName)
        {
            var matchedTypeName = GetParameterName(objectTypeDescriptor.Name);

            // since we want to create the data name we will need to craft the type name
            // by hand by using the GraphQL type name and the state namespace.
            var dataTypeName = new RuntimeTypeInfo(
                CreateDataTypeName(objectTypeDescriptor.Name),
                $"{objectTypeDescriptor.RuntimeType.Namespace}.State");

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

            foreach (PropertyDescriptor prop in objectTypeDescriptor.Properties)
            {
                if (prop.Type.IsEntityType())
                {
                    constructorCall.AddArgument(BuildMapMethodCall(matchedTypeName, prop));
                }
                else
                {
                    constructorCall.AddArgument($"{matchedTypeName}.{prop.Name}");
                }
            }

            return(IfBuilder
                   .New()
                   .SetCondition($"{_dataParameterName} is {dataTypeName} {matchedTypeName}")
                   .AddCode(
                       AssignmentBuilder
                       .New()
                       .SetLefthandSide(variableName)
                       .SetRighthandSide(constructorCall)));
        }
        private void AddScalarTypeDeserializerMethod(
            MethodBuilder methodBuilder,
            ILeafTypeDescriptor namedType)
        {
            MethodCallBuilder methodCall = MethodCallBuilder
                                           .New()
                                           .SetReturn()
                                           .SetMethodName(GetFieldName(namedType.Name) + "Parser", "Parse");

            if (namedType.SerializationType.ToString() == TypeNames.JsonElement)
            {
                methodCall.AddArgument($"{_obj}.{nameof(Nullable<JsonElement>.Value)}!");
            }
            else
            {
                var deserializeMethod = JsonUtils.GetParseMethod(namedType.SerializationType);
                methodCall.AddArgument(MethodCallBuilder
                                       .Inline()
                                       .SetMethodName(_obj, nameof(Nullable <JsonElement> .Value), deserializeMethod)
                                       .SetNullForgiving());
            }

            methodBuilder.AddCode(methodCall);
        }
        private MethodCallBuilder CreateResultInfoMethodCall(
            InterfaceTypeDescriptor resultNamedType,
            string concreteType)
        {
            MethodCallBuilder resultInfoConstructor = MethodCallBuilder
                                                      .Inline()
                                                      .SetMethodName($"new {concreteType}");

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

            return(resultInfoConstructor
                   .AddArgument(_entityIds)
                   .AddArgument($"{_session}.{TypeNames.IEntityUpdateSession_Version}"));
        }
        protected override void Generate(ITypeDescriptor typeDescriptor,
                                         CSharpSyntaxGeneratorSettings settings,
                                         CodeWriter writer,
                                         out string fileName,
                                         out string?path,
                                         out string ns)
        {
            ComplexTypeDescriptor descriptor =
                typeDescriptor as ComplexTypeDescriptor ??
                throw new InvalidOperationException(
                          "A result data factory can only be generated for complex types");

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

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

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

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

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

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

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

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

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

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

            var processed = new HashSet <string>();

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

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

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

            classBuilder.Build(writer);
        }
        protected override void Generate(
            CodeWriter writer,
            ITypeDescriptor typeDescriptor,
            out string fileName)
        {
            ComplexTypeDescriptor descriptor =
                typeDescriptor as ComplexTypeDescriptor ??
                throw new InvalidOperationException(
                          "A result data factory can only be generated for complex types");

            fileName = CreateResultFactoryName(descriptor.RuntimeType.Name);

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

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

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

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

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

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

            classBuilder
            .AddMethod("Create")
            .SetAccessModifier(AccessModifier.Public)
            .SetReturnType(descriptor.RuntimeType.Name)
            .AddParameter(_dataInfo, b => b.SetType(TypeNames.IOperationResultDataInfo))
            .AddCode(ifHasCorrectType)
            .AddEmptyLine()
            .AddCode(
                ExceptionBuilder
                .New(TypeNames.ArgumentException)
                .AddArgument(
                    $"\"{CreateResultInfoName(descriptor.RuntimeType.Name)} expected.\""));

            var processed = new HashSet <string>();

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

            CodeFileBuilder
            .New()
            .SetNamespace(descriptor.RuntimeType.NamespaceWithoutGlobal)
            .AddType(classBuilder)
            .Build(writer);
        }
Beispiel #17
0
 public ExceptionBuilder AddArgument(string value)
 {
     _method.AddArgument(value);
     return(this);
 }
        protected override void Generate(ITypeDescriptor typeDescriptor,
                                         CSharpSyntaxGeneratorSettings settings,
                                         CodeWriter writer,
                                         out string fileName,
                                         out string?path,
                                         out string ns)
        {
            // Setup class
            ComplexTypeDescriptor descriptor =
                typeDescriptor as ComplexTypeDescriptor ??
                throw new InvalidOperationException(
                          "A result entity mapper can only be generated for complex types");

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

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

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

            AddConstructorAssignedField(
                TypeNames.IEntityStore,
                _entityStore,
                entityStore,
                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.Entity
                                ? CreateEntityType(
                        descriptor.Name,
                        descriptor.RuntimeType.NamespaceWithoutGlobal)
                    .ToString()
                                : descriptor.Name)
                .SetName(_entity))
                                      .AddParameter(
                _snapshot,
                b => b.SetDefault("null")
                .SetType(TypeNames.IEntityStoreSnapshot.MakeNullable()));

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

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

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

            mapMethod.AddCode(constructorCall);

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

            classBuilder.AddMethod(mapMethod);

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

            classBuilder.Build(writer);
        }
Beispiel #19
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);
        }
Beispiel #20
0
        protected override void Generate(
            CodeWriter writer,
            OperationDescriptor descriptor,
            out string fileName,
            out string?path)
        {
            fileName = descriptor.RuntimeType.Name;
            path     = null;

            ClassBuilder classBuilder = ClassBuilder
                                        .New()
                                        .SetComment(
                XmlCommentBuilder
                .New()
                .SetSummary(
                    string.Format(
                        CodeGenerationResources.OperationServiceDescriptor_Description,
                        descriptor.Name))
                .AddCode(descriptor.BodyString))
                                        .AddImplements(descriptor.InterfaceType.ToString())
                                        .SetName(fileName);

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

            var runtimeTypeName =
                descriptor.ResultTypeReference.GetRuntimeType().Name;

            AddConstructorAssignedField(
                TypeNames.IOperationExecutor.WithGeneric(runtimeTypeName),
                _operationExecutor,
                classBuilder,
                constructorBuilder);

            AddInjectedSerializers(descriptor, constructorBuilder, classBuilder);

            if (descriptor is not SubscriptionOperationDescriptor)
            {
                classBuilder.AddMethod(CreateExecuteMethod(descriptor, runtimeTypeName));
            }

            classBuilder.AddMethod(CreateWatchMethod(descriptor, runtimeTypeName));
            classBuilder.AddMethod(CreateRequestMethod(descriptor));
            classBuilder.AddMethod(CreateRequestVariablesMethod(descriptor));

            AddFormatMethods(descriptor, classBuilder);

            classBuilder
            .AddProperty("ResultType")
            .SetType(TypeNames.Type)
            .AsLambda($"typeof({runtimeTypeName})")
            .SetInterface(TypeNames.IOperationRequestFactory);

            MethodCallBuilder createRequestCall = MethodCallBuilder
                                                  .New()
                                                  .SetReturn()
                                                  .SetMethodName(_createRequest);

            if (descriptor.Arguments.Count > 0)
            {
                createRequestCall.AddArgument($"{_variables}!");
            }

            classBuilder
            .AddMethod("Create")
            .SetReturnType(TypeNames.OperationRequest)
            .SetInterface(TypeNames.IOperationRequestFactory)
            .AddParameter(
                _variables,
                x => x.SetType(
                    TypeNames.IReadOnlyDictionary
                    .WithGeneric(TypeNames.String, TypeNames.Object.MakeNullable())
                    .MakeNullable()))
            .AddCode(createRequestCall);

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