Exemple #1
0
        public static ClassBuilder AddEquality(
            this ClassBuilder builder,
            string typeName,
            IReadOnlyList <PropertyDescriptor> properties)
        {
            builder.AddImplements(TypeNames.IEquatable.WithGeneric(typeName));
            builder.AddMethod(BuildEqualsMethod(typeName, properties));
            builder.AddMethod(BuildObjectEqualsMethod(typeName));
            builder.AddMethod(BuildGetHashCodeMethod(properties));

            return(builder);
        }
        protected override void Generate(
            CodeWriter writer,
            DependencyInjectionDescriptor descriptor,
            out string fileName)
        {
            fileName = ServiceCollectionExtensionsFromClientName(descriptor.Name);

            ClassBuilder factory = ClassBuilder
                                   .New(fileName)
                                   .SetStatic()
                                   .SetAccessModifier(AccessModifier.Public);

            factory
            .AddMethod($"Add{descriptor.Name}")
            .SetPublic()
            .SetStatic()
            .SetReturnType(TypeNames.IServiceCollection)
            .AddParameter(
                "services",
                x => x.SetThis().SetType(TypeNames.IServiceCollection))
            .AddParameter(
                "strategy",
                x => x.SetType(TypeNames.ExecutionStrategy)
                .SetDefault(
                    TypeNames.ExecutionStrategy + "." +
                    nameof(ExecutionStrategy.NetworkOnly)))
            .AddCode(GenerateMethodBody(descriptor));

            factory
            .AddMethod("ConfigureClient")
            .SetPrivate()
            .SetStatic()
            .SetReturnType(TypeNames.IServiceCollection)
            .AddParameter("services", x => x.SetType(TypeNames.IServiceCollection))
            .AddParameter("parentServices", x => x.SetType(TypeNames.IServiceProvider))
            .AddParameter(
                "strategy",
                x => x.SetType(TypeNames.ExecutionStrategy)
                .SetDefault(
                    TypeNames.ExecutionStrategy + "." +
                    nameof(ExecutionStrategy.NetworkOnly)))
            .AddCode(GenerateInternalMethodBody(descriptor));

            factory.AddClass(_clientServiceProvider);

            CodeFileBuilder
            .New()
            .SetNamespace(descriptor.Namespace)
            .AddType(factory)
            .Build(writer);
        }
Exemple #3
0
        public static MethodBuilder AddMethod(this ClassBuilder builder, string name)
        {
            MethodBuilder methodBuilder = MethodBuilder.New().SetName(name);

            builder.AddMethod(methodBuilder);
            return(methodBuilder);
        }
        private void AddDeserializeMethod(
            ClassBuilder classBuilder,
            ResultParserDeserializerMethodDescriptor methodDescriptor,
            string indent)
        {
            ImmutableQueue <ResultTypeComponentDescriptor> runtimeTypeComponents =
                ImmutableQueue.CreateRange <ResultTypeComponentDescriptor>(
                    methodDescriptor.RuntimeTypeComponents);

            classBuilder.AddMethod(
                MethodBuilder.New()
                .SetAccessModifier(AccessModifier.Private)
                .SetInheritance(Inheritance.Override)
                .SetReturnType(
                    $"{methodDescriptor.RuntimeType}?",
                    IsNullable(methodDescriptor.RuntimeTypeComponents))
                .SetReturnType(
                    $"{methodDescriptor.RuntimeType}",
                    !IsNullable(methodDescriptor.RuntimeTypeComponents))
                .SetName(methodDescriptor.Name)
                .AddParameter(ParameterBuilder.New()
                              .SetType(Types.JsonElement)
                              .SetName("obj"))
                .AddParameter(ParameterBuilder.New()
                              .SetType("string")
                              .SetName("field"))
                .AddCode(CreateDeserializeMethodBody(
                             methodDescriptor, runtimeTypeComponents, indent)));
        }
Exemple #5
0
        protected override void Generate(
            CodeWriter writer,
            EnumDescriptor descriptor,
            out string fileName)
        {
            fileName = NamingConventions.EnumParserNameFromEnumName(descriptor.Name);

            ClassBuilder classBuilder = ClassBuilder
                                        .New(fileName)
                                        .AddImplements(TypeNames.IInputValueFormatter)
                                        .AddImplements(
                TypeNames.ILeafValueParser.WithGeneric(TypeNames.String, descriptor.Name));

            const string serializedValueParamName = "serializedValue";

            classBuilder
            .AddMethod("Parse")
            .AddParameter(ParameterBuilder.New()
                          .SetName(serializedValueParamName)
                          .SetType(TypeNames.String))
            .SetAccessModifier(AccessModifier.Public)
            .SetReturnType(descriptor.Name)
            .AddCode(CreateEnumParsingSwitch(serializedValueParamName, descriptor));

            const string runtimeValueParamName = "runtimeValue";

            classBuilder
            .AddMethod("Format")
            .SetAccessModifier(AccessModifier.Public)
            .SetReturnType("object")
            .AddParameter(ParameterBuilder.New()
                          .SetType(TypeNames.Object.MakeNullable())
                          .SetName(runtimeValueParamName))
            .AddCode(CreateEnumFormatingSwitch(runtimeValueParamName, descriptor));

            classBuilder
            .AddProperty("TypeName")
            .AsLambda(descriptor.Name.AsStringToken())
            .SetPublic()
            .SetType(TypeNames.String);

            CodeFileBuilder
            .New()
            .SetNamespace(descriptor.Namespace)
            .AddType(classBuilder)
            .Build(writer);
        }
Exemple #6
0
        protected override void Generate(
            CodeWriter writer,
            OperationDescriptor descriptor,
            out string fileName)
        {
            var documentName = CreateDocumentTypeName(descriptor.Name);

            fileName = documentName;

            string operationKind = descriptor switch
            {
                MutationOperationDescriptor => "Mutation",
                QueryOperationDescriptor => "Query",
                SubscriptionOperationDescriptor => "Subscription",
                _ => throw new ArgumentOutOfRangeException(nameof(descriptor))
            };

            ClassBuilder classBuilder = ClassBuilder
                                        .New()
                                        .AddImplements(TypeNames.IDocument)
                                        .SetName(fileName);

            classBuilder
            .AddConstructor()
            .SetPrivate();

            classBuilder
            .AddProperty("Instance")
            .SetStatic()
            .SetType(documentName)
            .SetValue($"new {documentName}()");

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

            classBuilder
            .AddProperty("Body")
            .SetType(TypeNames.IReadOnlySpan.WithGeneric(TypeNames.Byte))
            .AsLambda(GetByteArray(descriptor.BodyString));

            classBuilder
            .AddMethod("ToString")
            .SetPublic()
            .SetOverride()
            .SetReturnType(TypeNames.String)
            .AddCode(MethodCallBuilder
                     .New()
                     .SetReturn()
                     .SetMethodName(TypeNames.EncodingUtf8, nameof(Encoding.UTF8.GetString))
                     .AddArgument("Body"));

            CodeFileBuilder
            .New()
            .SetNamespace(descriptor.Namespace)
            .AddType(classBuilder)
            .Build(writer);
        }
Exemple #7
0
        private void AddBuildMethod(
            InterfaceTypeDescriptor resultNamedType,
            ClassBuilder classBuilder)
        {
            var responseParameterName = "response";

            var buildMethod = MethodBuilder
                              .New()
                              .SetAccessModifier(AccessModifier.Public)
                              .SetName("Build")
                              .SetReturnType(
                TypeReferenceBuilder.New()
                .SetName(TypeNames.IOperationResult)
                .AddGeneric(resultNamedType.RuntimeType.Name))
                              .AddParameter(
                ParameterBuilder.New()
                .SetType(
                    TypeReferenceBuilder.New()
                    .SetName(TypeNames.Response)
                    .AddGeneric(TypeNames.JsonDocument)
                    .SetName(TypeNames.Response))
                .SetName(responseParameterName));

            var concreteResultType =
                CreateResultInfoName(resultNamedType.ImplementedBy.First().RuntimeType.Name);

            buildMethod.AddCode(
                AssignmentBuilder.New()
                .SetLefthandSide(
                    $"({resultNamedType.RuntimeType.Name} Result, {concreteResultType} " +
                    "Info)? data")
                .SetRighthandSide("null"));

            buildMethod.AddEmptyLine();
            buildMethod.AddCode(
                IfBuilder.New()
                .SetCondition(
                    ConditionBuilder.New()
                    .Set("response.Body is not null")
                    .And("response.Body.RootElement.TryGetProperty(\"data\"," +
                         $" out {TypeNames.JsonElement} obj)"))
                .AddCode("data = BuildData(obj);"));

            buildMethod.AddEmptyLine();
            buildMethod.AddCode(
                MethodCallBuilder.New()
                .SetPrefix("return new ")
                .SetMethodName(
                    TypeNames.OperationResult.WithGeneric(resultNamedType.RuntimeType.Name))
                .AddArgument("data?.Result")
                .AddArgument("data?.Info")
                .AddArgument(_resultDataFactoryFieldName)
                .AddArgument("null"));

            classBuilder.AddMethod(buildMethod);
        }
Exemple #8
0
        protected override void Generate(
            CodeWriter writer,
            OperationDescriptor operationDescriptor,
            out string fileName)
        {
            fileName = operationDescriptor.Name;

            ClassBuilder classBuilder = ClassBuilder
                                        .New()
                                        .SetName(fileName);

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

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

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

            AddInjectedSerializers(operationDescriptor, constructorBuilder, classBuilder);

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

            classBuilder.AddMethod(CreateWatchMethod(operationDescriptor, runtimeTypeName));
            classBuilder.AddMethod(CreateRequestMethod(operationDescriptor));

            AddFormatMethods(operationDescriptor, classBuilder);

            CodeFileBuilder
            .New()
            .SetNamespace(operationDescriptor.Namespace)
            .AddType(classBuilder)
            .Build(writer);
        }
Exemple #9
0
        public static ClassBuilder AddMethod(
            this ClassBuilder builder,
            string name,
            Action <MethodBuilder> configure)
        {
            MethodBuilder methodBuilder = MethodBuilder.New().SetName(name);

            configure(methodBuilder);
            builder.AddMethod(methodBuilder);
            return(builder);
        }
Exemple #10
0
        protected override void Generate(
            CodeWriter writer,
            EnumTypeDescriptor descriptor,
            out string fileName)
        {
            const string serializedValue = nameof(serializedValue);
            const string runtimeValue    = nameof(runtimeValue);

            fileName = CreateEnumParserName(descriptor.Name);

            ClassBuilder classBuilder = ClassBuilder
                                        .New(fileName)
                                        .AddImplements(IInputValueFormatter)
                                        .AddImplements(ILeafValueParser.WithGeneric(String, descriptor.Name));

            classBuilder
            .AddMethod("Parse")
            .AddParameter(serializedValue, x => x.SetType(String))
            .SetAccessModifier(AccessModifier.Public)
            .SetReturnType(descriptor.Name)
            .AddCode(CreateEnumParsingSwitch(serializedValue, descriptor));

            classBuilder
            .AddMethod("Format")
            .SetAccessModifier(AccessModifier.Public)
            .SetReturnType(Object)
            .AddParameter(runtimeValue, x => x.SetType(Object.MakeNullable()))
            .AddCode(CreateEnumFormattingSwitch(runtimeValue, descriptor));

            classBuilder
            .AddProperty("TypeName")
            .AsLambda(descriptor.Name.AsStringToken())
            .SetPublic()
            .SetType(String);

            CodeFileBuilder
            .New()
            .SetNamespace(descriptor.RuntimeType.NamespaceWithoutGlobal)
            .AddType(classBuilder)
            .Build(writer);
        }
Exemple #11
0
 private static void AddToStringMethod(
     ClassBuilder classBuilder,
     string originalDocument)
 {
     classBuilder
     .AddMethod(MethodBuilder.New()
                .SetAccessModifier(AccessModifier.Public)
                .SetInheritance(Inheritance.Override)
                .SetReturnType("string")
                .SetName("ToString")
                .AddCode(CreateToStringBody(originalDocument)));
 }
Exemple #12
0
        public static MethodBuilder AddMethod(this ClassBuilder builder, string?name = null)
        {
            MethodBuilder methodBuilder = MethodBuilder.New();

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

            builder.AddMethod(methodBuilder);
            return(methodBuilder);
        }
        protected override void Generate(
            CodeWriter writer,
            EntityIdFactoryDescriptor descriptor,
            out string fileName)
        {
            fileName = descriptor.Name;

            ClassBuilder classBuilder = ClassBuilder
                .New()
                .SetStatic()
                .SetAccessModifier(AccessModifier.Public)
                .SetName(fileName);

            classBuilder
                .AddMethod("CreateEntityId")
                .SetStatic()
                .SetAccessModifier(AccessModifier.Public)
                .SetReturnType(TypeNames.EntityId)
                .AddParameter(_obj, x => x.SetType(TypeNames.JsonElement))
                .AddCode(CreateEntityIdBody(descriptor));

            foreach (var entity in descriptor.Entities)
            {
                classBuilder
                    .AddMethod($"Create{entity.Name}EntityId")
                    .SetAccessModifier(AccessModifier.Private)
                    .SetStatic()
                    .SetReturnType(TypeNames.EntityId)
                    .AddParameter(_obj, x => x.SetType(TypeNames.JsonElement))
                    .AddParameter(_type, x => x.SetType(TypeNames.String))
                    .AddCode(CreateSpecificEntityIdBody(entity));
            }

            CodeFileBuilder
                .New()
                .SetNamespace(descriptor.Namespace)
                .AddType(classBuilder)
                .Build(writer);
        }
Exemple #14
0
 private void AddInitializeMethod(
     IReadOnlyList <ValueSerializerDescriptor> serializerDescriptors,
     ClassBuilder builder)
 {
     builder
     .AddMethod(MethodBuilder.New()
                .SetAccessModifier(AccessModifier.Public)
                .SetName("Initialize")
                .AddParameter(ParameterBuilder.New()
                              .SetType(Types.IValueSerializerCollection)
                              .SetName("serializerResolver"))
                .AddCode(CreateInitializeBody(serializerDescriptors, CodeWriter.Indent)));
 }
Exemple #15
0
        protected override void Generate(
            CodeWriter writer,
            InputObjectTypeDescriptor namedTypeDescriptor,
            out string fileName)
        {
            const string serializerResolver = nameof(serializerResolver);
            const string runtimeValue       = nameof(runtimeValue);
            const string value = nameof(value);

            fileName = CreateInputValueFormatter(namedTypeDescriptor);

            NameString typeName = namedTypeDescriptor.Name;

            ClassBuilder classBuilder = ClassBuilder
                                        .New()
                                        .SetName(fileName)
                                        .AddImplements(TypeNames.IInputValueFormatter);

            var neededSerializers = namedTypeDescriptor
                                    .Properties
                                    .GroupBy(x => x.Type.Name)
                                    .ToDictionary(x => x, x => x.First());

            //  Initialize Method

            CodeBlockBuilder initialize = classBuilder
                                          .AddMethod("Initialize")
                                          .SetPublic()
                                          .AddParameter(serializerResolver, x => x.SetType(TypeNames.ISerializerResolver))
                                          .AddBody();

            foreach (var property in neededSerializers.Values)
            {
                if (property.Type.GetName().Value is { } name)
                {
                    var propertyName = GetFieldName(name) + "Formatter";

                    initialize
                    .AddAssigment(propertyName)
                    .AddMethodCall()
                    .SetMethodName(
                        serializerResolver,
                        nameof(ISerializerResolver.GetInputValueFormatter))
                    .AddArgument(name.AsStringToken());

                    classBuilder
                    .AddField(propertyName)
                    .SetAccessModifier(AccessModifier.Private)
                    .SetType(TypeNames.IInputValueFormatter)
                    .SetValue("default!");
                }
Exemple #16
0
 private void AddDeserializeMethod(ClassBuilder builder)
 {
     builder
     .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(CreateDeserializeBody(CodeWriter.Indent)));
 }
        private static void AddGetVariableValues(
            ClassBuilder classBuilder,
            IReadOnlyList <OperationArgumentDescriptor> arguments,
            string indent)
        {
            MethodBuilder methodBuilder = MethodBuilder.New()
                                          .SetAccessModifier(AccessModifier.Public)
                                          .SetReturnType(
                "global::System.Collections.Generic.IReadOnlyList<" +
                "global::StrawberryShake.VariableValue>")
                                          .SetName("GetVariableValues")
                                          .AddCode(CreateGetVariableValuesBody(arguments, indent));

            classBuilder.AddMethod(methodBuilder);
        }
Exemple #18
0
 private static void AddFormatMethods(
     OperationDescriptor operationDescriptor,
     ClassBuilder classBuilder)
 {
     foreach (var argument in operationDescriptor.Arguments)
     {
         classBuilder
         .AddMethod()
         .SetPrivate()
         .SetReturnType(TypeNames.Object.MakeNullable())
         .SetName("Format" + GetPropertyName(argument.Name))
         .AddParameter(_value, x => x.SetType(argument.Type.ToBuilder()))
         .AddCode(GenerateSerializer(argument.Type, _value));
     }
 }
Exemple #19
0
 private void AddSerializeMethod(
     InputModelSerializerDescriptor descriptor,
     ClassBuilder builder)
 {
     builder
     .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(CreateSerializeBody(descriptor, CodeWriter.Indent)));
 }
Exemple #20
0
 private static void AddAddClientMethod(
     ClassBuilder builder,
     DependencyInjectionDescriptor descriptor,
     string indent)
 {
     builder.AddMethod(MethodBuilder.New()
                       .SetAccessModifier(AccessModifier.Public)
                       .SetStatic()
                       .SetReturnType(
                           "global::StrawberryShake.Configuration.IOperationClientBuilder")
                       .SetName($"Add{descriptor.ClientName}")
                       .AddParameter(ParameterBuilder.New()
                                     .SetType(
                                         "this global::Microsoft.Extensions.DependencyInjection." +
                                         "IServiceCollection")
                                     .SetName("serviceCollection"))
                       .AddCode(CreateAddClientBody(descriptor, indent)));
 }
Exemple #21
0
 private void AddTypeSerializerMethods(
     IReadOnlyList <InputTypeSerializerMethodDescriptor> descriptors,
     ClassBuilder builder)
 {
     foreach (InputTypeSerializerMethodDescriptor descriptor in descriptors)
     {
         builder
         .AddMethod(MethodBuilder.New()
                    .SetAccessModifier(AccessModifier.Private)
                    .SetName(descriptor.Name)
                    .SetReturnType("object?", NullableRefTypes)
                    .SetReturnType("object", !NullableRefTypes)
                    .AddParameter(ParameterBuilder.New()
                                  .SetName("value")
                                  .SetType("object?", NullableRefTypes)
                                  .SetType("object", !NullableRefTypes))
                    .AddCode(CreateTypeSerializeBody(descriptor, CodeWriter.Indent)));
     }
 }
        private void AddDeserializeMethod(
            ITypeDescriptor typeReference,
            ClassBuilder classBuilder,
            HashSet <string> processed)
        {
            string methodName = DeserializerMethodNameFromTypeName(typeReference);

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

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

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

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

                methodBuilder
                .AddCode(jsonElementNullCheck)
                .AddEmptyLine();

                AddDeserializeMethodBody(classBuilder, methodBuilder, typeReference, processed);
            }
        }
 private void AddParseMethod(
     ClassBuilder classBuilder,
     ResultParserMethodDescriptor methodDescriptor,
     string indent)
 {
     classBuilder.AddMethod(
         MethodBuilder.New()
         .SetAccessModifier(AccessModifier.Private)
         .SetInheritance(Inheritance.Override)
         .SetReturnType(
             $"{methodDescriptor.ResultType}?",
             IsNullable(methodDescriptor.ResultType.Components))
         .SetReturnType(
             $"{methodDescriptor.ResultType}",
             !IsNullable(methodDescriptor.ResultType.Components))
         .SetName(methodDescriptor.Name)
         .AddParameter(ParameterBuilder.New()
                       .SetType(Types.JsonElement)
                       .SetName("parent"))
         .AddCode(CreateParseMethodBody(methodDescriptor, indent)));
 }
        private void AddDeserializeMethod(
            ITypeDescriptor typeReference,
            ClassBuilder classBuilder,
            HashSet <string> processed)
        {
            string methodName = DeserializerMethodNameFromTypeName(typeReference);

            if (processed.Add(methodName))
            {
                var returnType = typeReference.ToEntityIdBuilder();

                var methodBuilder = MethodBuilder.New()
                                    .SetAccessModifier(AccessModifier.Private)
                                    .SetName(methodName)
                                    .SetReturnType(returnType)
                                    .AddParameter(
                    ParameterBuilder.New()
                    .SetType(_jsonElementParamName)
                    .SetName(_objParamName));
                if (typeReference.IsEntityType() || typeReference.ContainsEntity())
                {
                    methodBuilder.AddParameter(
                        ParameterBuilder.New()
                        .SetType($"{TypeNames.ISet}<{TypeNames.EntityId}>")
                        .SetName(_entityIdsParam));
                }

                methodBuilder.AddCode(
                    EnsureProperNullability(isNonNullType: typeReference.IsNonNullableType()));

                classBuilder.AddMethod(methodBuilder);

                AddDeserializeMethodBody(
                    classBuilder,
                    methodBuilder,
                    typeReference,
                    processed);
            }
        }
Exemple #25
0
        protected override void Generate(
            CodeWriter writer,
            InputObjectTypeDescriptor namedTypeDescriptor,
            out string fileName)
        {
            fileName = CreateInputValueFormatter(namedTypeDescriptor);

            NameString   typeName     = namedTypeDescriptor.Name;
            ClassBuilder classBuilder = ClassBuilder.New()
                                        .SetName(fileName)
                                        .AddImplements(TypeNames.IInputValueFormatter);

            var neededSerializers = namedTypeDescriptor.Properties
                                    .ToLookup(x => x.Type.Name)
                                    .Select(x => x.First())
                                    .ToDictionary(x => x.Type.Name);

            //  Initialize Method

            CodeBlockBuilder initialize = classBuilder
                                          .AddMethod("Initialize")
                                          .SetPublic()
                                          .AddParameter("serializerResolver", x => x.SetType(TypeNames.ISerializerResolver))
                                          .AddBody();

            foreach (var property in neededSerializers.Values)
            {
                if (property.Type.GetName().Value is { } name)
                {
                    MethodCallBuilder call = MethodCallBuilder.New()
                                             .SetMethodName("serializerResolver." +
                                                            nameof(ISerializerResolver.GetInputValueFormatter))
                                             .AddArgument(name.AsStringToken() ?? "")
                                             .SetPrefix($"{GetFieldName(name)}Formatter = ");

                    initialize.AddCode(call);
                }
        public static ClassBuilder AddEquality(
            this ClassBuilder builder,
            string typeName,
            IReadOnlyList <PropertyDescriptor> properties)
        {
            const string obj   = nameof(obj);
            const string other = nameof(other);

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

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

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

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

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

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

            return(builder);
        }
        private void AddBuildDataMethod(
            InterfaceTypeDescriptor resultNamedType,
            ClassBuilder classBuilder)
        {
            var concreteType =
                CreateResultInfoName(resultNamedType.ImplementedBy.First().RuntimeType.Name);

            MethodBuilder buildDataMethod = classBuilder
                                            .AddMethod()
                                            .SetPrivate()
                                            .SetName("BuildData")
                                            .SetReturnType($"({resultNamedType.RuntimeType.Name}, {concreteType})")
                                            .AddParameter(_obj, x => x.SetType(TypeNames.JsonElement))
                                            .AddCode(
                AssignmentBuilder
                .New()
                .SetLefthandSide($"using {TypeNames.IEntityUpdateSession} {_session}")
                .SetRighthandSide(
                    MethodCallBuilder
                    .Inline()
                    .SetMethodName(_entityStore, nameof(IEntityStore.BeginUpdate))))
                                            .AddCode(
                AssignmentBuilder
                .New()
                .SetLefthandSide($"var {_entityIds}")
                .SetRighthandSide(MethodCallBuilder
                                  .Inline()
                                  .SetNew()
                                  .SetMethodName(TypeNames.HashSet)
                                  .AddGeneric(TypeNames.EntityId)))
                                            .AddEmptyLine();

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

            buildDataMethod
            .AddEmptyLine()
            .AddCode(
                AssignmentBuilder
                .New()
                .SetLefthandSide($"var {_resultInfo}")
                .SetRighthandSide(
                    CreateResultInfoMethodCall(resultNamedType, concreteType)))
            .AddEmptyLine()
            .AddCode(
                TupleBuilder
                .Inline()
                .SetDetermineStatement(true)
                .SetReturn()
                .AddMember(MethodCallBuilder
                           .Inline()
                           .SetMethodName(
                               _resultDataFactory,
                               nameof(IOperationResultDataFactory <object> .Create))
                           .AddArgument(_resultInfo))
                .AddMember(_resultInfo));
        }
        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);
        }
Exemple #29
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);
        }
Exemple #30
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 className = CreateResultInfoName(complexTypeDescriptor.RuntimeType.Name);

            fileName = className;

            ClassBuilder classBuilder = ClassBuilder
                                        .New()
                                        .AddImplements(TypeNames.IOperationResultDataInfo)
                                        .SetName(fileName);

            ConstructorBuilder constructorBuilder = classBuilder
                                                    .AddConstructor()
                                                    .SetTypeName(complexTypeDescriptor.RuntimeType.Name);

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

                // Add Property to class
                classBuilder
                .AddProperty(prop.Name)
                .SetType(propTypeBuilder)
                .SetPublic();

                // Add initialization of property to the constructor
                var paramName = GetParameterName(prop.Name);
                constructorBuilder.AddParameter(paramName).SetType(propTypeBuilder);
                constructorBuilder.AddCode(
                    AssignmentBuilder
                    .New()
                    .SetLefthandSide(prop.Name)
                    .SetRighthandSide(paramName));
            }

            classBuilder
            .AddProperty("EntityIds")
            .SetType(TypeNames.IReadOnlyCollection.WithGeneric(TypeNames.EntityId))
            .AsLambda(_entityIds);

            classBuilder
            .AddProperty("Version")
            .SetType(TypeNames.UInt64)
            .AsLambda(_version);

            AddConstructorAssignedField(
                TypeNames.IReadOnlyCollection.WithGeneric(TypeNames.EntityId),
                _entityIds,
                classBuilder,
                constructorBuilder);

            AddConstructorAssignedField(
                TypeNames.UInt64,
                _version,
                classBuilder,
                constructorBuilder,
                true);


            // WithVersion
            const string version = nameof(version);

            classBuilder
            .AddMethod("WithVersion")
            .SetAccessModifier(AccessModifier.Public)
            .SetReturnType(TypeNames.IOperationResultDataInfo)
            .AddParameter(version, x => x.SetType(TypeNames.UInt64))
            .AddCode(MethodCallBuilder
                     .New()
                     .SetReturn()
                     .SetNew()
                     .SetMethodName(className)
                     .AddArgumentRange(
                         complexTypeDescriptor.Properties.Select(x => x.Name.Value))
                     .AddArgument(_entityIds)
                     .AddArgument(version));

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