protected void AddConstructorAssignedField(
            TypeReferenceBuilder type,
            string fieldName,
            ClassBuilder classBuilder,
            ConstructorBuilder constructorBuilder,
            bool skipNullCheck = false)
        {
            var paramName = fieldName.TrimStart('_');

            classBuilder.AddField()
            .SetReadOnly()
            .SetName(fieldName)
            .SetType(type);

            AssignmentBuilder assignment = AssignmentBuilder
                                           .New()
                                           .SetLefthandSide(fieldName)
                                           .SetRighthandSide(paramName);

            if (!skipNullCheck)
            {
                assignment.AssertNonNull();
            }

            constructorBuilder
            .AddCode(assignment)
            .AddParameter(paramName, b => b.SetType(type));
        }
Exemple #2
0
        private static void AddInjectedSerializers(
            OperationDescriptor descriptor,
            ConstructorBuilder constructorBuilder,
            ClassBuilder classBuilder)
        {
            var neededSerializers = descriptor
                                    .Arguments
                                    .GroupBy(x => x.Type.Name)
                                    .ToDictionary(x => x.Key, x => x.First());

            if (!neededSerializers.Any())
            {
                return;
            }

            constructorBuilder
            .AddParameter(_serializerResolver)
            .SetType(TypeNames.ISerializerResolver);

            foreach (var property in neededSerializers.Values)
            {
                if (property.Type.GetName().Value is { } name)
                {
                    var fieldName = $"{GetFieldName(name)}Formatter";
                    constructorBuilder
                    .AddCode(
                        AssignmentBuilder
                        .New()
                        .SetLefthandSide(fieldName)
                        .SetRighthandSide(
                            MethodCallBuilder
                            .Inline()
                            .SetMethodName(
                                _serializerResolver,
                                "GetInputValueFormatter")
                            .AddArgument(name.AsStringToken())));

                    classBuilder
                    .AddField()
                    .SetName(fieldName)
                    .SetAccessModifier(AccessModifier.Private)
                    .SetType(TypeNames.IInputValueFormatter)
                    .SetReadOnly();
                }
Exemple #3
0
        protected override void Generate(ITypeDescriptor typeDescriptor,
                                         CSharpSyntaxGeneratorSettings settings,
                                         CodeWriter writer,
                                         out string fileName,
                                         out string?path,
                                         out string ns)
        {
            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;
            path     = State;
            ns       = CreateStateNamespace(complexTypeDescriptor.RuntimeType.NamespaceWithoutGlobal);

            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.ToStateTypeReference();

                // Add Property to class
                classBuilder
                .AddProperty(prop.Name)
                .SetComment(prop.Description)
                .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(settings.IsStoreEnabled()
                    ? CodeInlineBuilder.From(_entityIds)
                    : MethodCallBuilder.Inline()
                      .SetMethodName(TypeNames.Array, "Empty")
                      .AddGeneric(TypeNames.EntityId));

            classBuilder
            .AddProperty("Version")
            .SetType(TypeNames.UInt64)
            .AsLambda(settings.IsStoreEnabled() ? _version : "0");

            if (settings.IsStoreEnabled())
            {
                AddConstructorAssignedField(
                    TypeNames.IReadOnlyCollection.WithGeneric(TypeNames.EntityId),
                    _entityIds,
                    entityIds,
                    classBuilder,
                    constructorBuilder);

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

            // WithVersion
            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))
                     .If(settings.IsStoreEnabled(),
                         x => x.AddArgument(_entityIds).AddArgument(version)));

            classBuilder.Build(writer);
        }
        protected override void Generate(
            CodeWriter writer,
            ResultBuilderDescriptor resultBuilderDescriptor,
            out string fileName,
            out string?path)
        {
            InterfaceTypeDescriptor resultTypeDescriptor =
                resultBuilderDescriptor.ResultNamedType as InterfaceTypeDescriptor
                ?? throw new InvalidOperationException(
                          "A result type can only be generated for complex types");

            fileName = resultBuilderDescriptor.RuntimeType.Name;
            path     = State;

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

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

            classBuilder
            .AddImplements(
                TypeNames.IOperationResultBuilder.WithGeneric(
                    TypeNames.JsonDocument,
                    resultTypeDescriptor.RuntimeType.ToString()));

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

            AddConstructorAssignedField(
                TypeNames.IEntityIdSerializer,
                _idSerializer,
                classBuilder,
                constructorBuilder);

            AddConstructorAssignedField(
                TypeNames.IOperationResultDataFactory
                .WithGeneric(resultTypeDescriptor.RuntimeType.ToString()),
                _resultDataFactory,
                classBuilder,
                constructorBuilder);

            constructorBuilder
            .AddParameter(_serializerResolver)
            .SetType(TypeNames.ISerializerResolver);

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

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

                classBuilder
                .AddField(parserFieldName)
                .SetReadOnly()
                .SetType(
                    TypeNames.ILeafValueParser
                    .WithGeneric(valueParser.SerializedType, valueParser.RuntimeType));

                MethodCallBuilder getLeaveValueParser = MethodCallBuilder
                                                        .Inline()
                                                        .SetMethodName(_serializerResolver, "GetLeafValueParser")
                                                        .AddGeneric(valueParser.SerializedType.ToString())
                                                        .AddGeneric(valueParser.RuntimeType.ToString())
                                                        .AddArgument(valueParser.Name.AsStringToken());

                constructorBuilder.AddCode(
                    AssignmentBuilder
                    .New()
                    .SetAssertNonNull()
                    .SetAssertException(
                        ExceptionBuilder
                        .Inline(TypeNames.ArgumentException)
                        .AddArgument(
                            $"\"No serializer for type `{valueParser.Name}` found.\""))
                    .SetLefthandSide(parserFieldName)
                    .SetRighthandSide(getLeaveValueParser));
            }

            AddBuildMethod(resultTypeDescriptor, classBuilder);

            AddBuildDataMethod(resultTypeDescriptor, classBuilder);

            var processed = new HashSet <string>();

            AddRequiredDeserializeMethods(resultTypeDescriptor, classBuilder, processed);

            CodeFileBuilder
            .New()
            .SetNamespace(resultBuilderDescriptor.RuntimeType.NamespaceWithoutGlobal)
            .AddType(classBuilder)
            .Build(writer);
        }
        protected override void Generate(
            CodeWriter writer,
            DataTypeDescriptor descriptor,
            out string fileName,
            out string?path)
        {
            fileName = descriptor.RuntimeType.Name;
            path     = State;

            AbstractTypeBuilder typeBuilder;
            ConstructorBuilder? constructorBuilder = null;

            if (descriptor.IsInterface)
            {
                typeBuilder = InterfaceBuilder
                              .New()
                              .SetComment(descriptor.Documentation)
                              .SetName(fileName);

                typeBuilder
                .AddProperty(WellKnownNames.TypeName)
                .SetType(TypeNames.String);
            }
            else
            {
                ClassBuilder classBuilder = ClassBuilder
                                            .New()
                                            .SetComment(descriptor.Documentation)
                                            .SetName(fileName);

                typeBuilder = classBuilder;

                classBuilder
                .AddProperty(WellKnownNames.TypeName)
                .SetPublic()
                .SetType(TypeNames.String);

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

                constructorBuilder
                .AddParameter(WellKnownNames.TypeName)
                .SetType(TypeNames.String)
                .SetName(WellKnownNames.TypeName);

                constructorBuilder
                .AddCode(
                    AssignmentBuilder
                    .New()
                    .SetLefthandSide("this." + WellKnownNames.TypeName)
                    .SetRighthandSide(WellKnownNames.TypeName)
                    .AssertNonNull());
            }

            // Add Properties to class
            foreach (PropertyDescriptor property in descriptor.Properties)
            {
                if (property.Name.Value.EqualsOrdinal(WellKnownNames.TypeName))
                {
                    continue;
                }

                TypeReferenceBuilder propertyType = property.Type.ToStateTypeReference();

                typeBuilder
                .AddProperty(property.Name)
                .SetComment(property.Description)
                .SetType(propertyType)
                .SetPublic();

                var parameterName = GetParameterName(property.Name);

                constructorBuilder?
                .AddParameter(parameterName)
                .SetType(propertyType)
                .SetDefault("null");

                constructorBuilder?
                .AddCode(AssignmentBuilder
                         .New()
                         .SetLefthandSide(property.Name)
                         .SetRighthandSide(parameterName));
            }

            // implement interfaces
            typeBuilder.AddImplementsRange(descriptor.Implements.Select(CreateDataTypeName));

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