Exemple #1
0
        internal static SourceCode Generate(SourceGenerationOptions options)
        {
            using var builder = new SourceBuilder()
                                .WriteLine(GeneratedFilesHeader)
                                .WriteLine("using System;")
                                .WriteLine()
                                .WriteLine($"namespace {RootNamespace}")
                                .WriteOpeningBracket();

            if (options.GenerateXmlDocument)
            {
                builder
                .WriteLine("/// <summary>")
                .WriteLine("/// Specifies that the annotated class can be mapped from the provided <see cref=\"SourceType\"/>.")
                .WriteLine("/// </summary>");
            }

            builder
            .WriteLine("[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]")
            .WriteLine($"public sealed class {AttributeName}Attribute : Attribute")
            .WriteOpeningBracket();

            if (options.GenerateXmlDocument)
            {
                builder
                .WriteLine("/// <summary>")
                .WriteLine($"/// Initializes a new instance of the <see cref=\"{AttributeName}Attribute\"/> class with the specified <paramref name=\"sourceType\"/>.")
                .WriteLine("/// </summary>")
                .WriteLine("/// <param name=\"sourceType\">The type of to map from.</param>");
            }

            builder
            .WriteLine($"public {AttributeName}Attribute(Type sourceType)")
            .WriteOpeningBracket()
            .WriteLine("SourceType = sourceType;")
            .WriteClosingBracket()
            .WriteLine();

            if (options.GenerateXmlDocument)
            {
                builder
                .WriteLine("/// <summary>")
                .WriteLine("/// Gets the type to map from.")
                .WriteLine("/// </summary>");
            }

            builder
            .WriteLine("public Type SourceType { get; }")
            .WriteClosingBracket()     // class
            .WriteClosingBracket();    // namespace

            return(new(builder.ToString(), $"{AttributeName}Attribute.g.cs"));
        }
Exemple #2
0
        internal static SourceCode Generate(SourceGenerationOptions options)
        {
            using var builder = new SourceBuilder()
                                .WriteLine(GeneratedFilesHeader)
                                .WriteNullableContextOptionIf(options.SupportNullableReferenceTypes)
                                .WriteLine()
                                .WriteLine("using System;")
                                .WriteLine()
                                .WriteLine($"namespace {RootNamespace}")
                                .WriteOpeningBracket();

            if (options.GenerateXmlDocument)
            {
                builder
                .WriteLine("/// <summary>")
                .WriteLine("/// Specifies the mapping behavior of the annotated property.")
                .WriteLine("/// </summary>")
                .WriteLine("/// <remarks>")
                .WriteLine($"/// {AttributeClassName} has a number of uses:")
                .WriteLine("/// <list type=\"bullet\">")
                .WriteLine("/// <item><description>By default properties with same name will get mapped. This attribute allows the names to be different.</description></item>")
                .WriteLine("/// <item><description>Indicates that a property should be mapped when member serialization is set to opt-in.</description></item>")
                .WriteLine("/// </list>")
                .WriteLine("/// </remarks>");
            }

            builder
            .WriteLine("[AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = true)]")
            .WriteLine($"public sealed class {AttributeClassName} : Attribute")
            .WriteOpeningBracket();

            if (options.GenerateXmlDocument)
            {
                builder
                .WriteLine("/// <summary>")
                .WriteLine("/// Gets or sets the property name of the object to mapping from.")
                .WriteLine("/// </summary>");
            }

            builder
            .WriteLine($"public string{options.NullableReferenceSyntax} {SourcePropertyNamePropertyName} {{ get; set; }}")
            .WriteClosingBracket()     // class
            .WriteClosingBracket();    // namespace


            return(new(builder.ToString(), $"{AttributeClassName}.g.cs"));
        }
Exemple #3
0
        internal static SourceCode Generate(SourceGenerationOptions options)
        {
            using var builder = new SourceBuilder()
                                .WriteLine(GeneratedFilesHeader)
                                .WriteNullableContextOptionIf(options.SupportNullableReferenceTypes)
                                .WriteLine()
                                .WriteLine($"namespace {RootNamespace}")
                                .WriteOpeningBracket();

            if (options.GenerateXmlDocument)
            {
                builder
                .WriteLine("/// <summary>")
                .WriteLine("/// Converts the value of <typeparamref name=\"TSource\"/> to <typeparamref name=\"TDestination\"/>.")
                .WriteLine("/// </summary>")
                .WriteLine("/// <typeparam name=\"TSource\">The type to convert from.</typeparam>")
                .WriteLine("/// <typeparam name=\"TDestination\">The type to convert to.</typeparam>");
            }

            builder
            .WriteLine($"public interface {InterfaceName}<in TSource, out TDestination>")
            .WriteOpeningBracket();

            if (options.GenerateXmlDocument)
            {
                builder
                .WriteLine("/// <summary>")
                .WriteLine("/// Converts the value of <paramref name=\"source\"/> object to <typeparamref name=\"TDestination\"/>.")
                .WriteLine("/// </summary>")
                .WriteLine("/// <param name=\"source\">The <see cref=\"TSource\"/> to convert.</param>")
                .WriteLine($"/// <param name=\"converterParameters\">The parameter list passed to the <see cref=\"{MapTypeConverterAttributeSource.AttributeClassName}\"/></param>")
                .WriteLine("/// <returns><typeparamref name=\"TDestination\"/> object.</returns>");
            }

            builder
            .WriteLine($"TDestination Convert(TSource source, object[]{options.NullableReferenceSyntax} converterParameters);")
            .WriteClosingBracket()
            .WriteClosingBracket();

            return(new(builder.ToString(), $"{InterfaceName}.g.cs"));
        }
Exemple #4
0
        internal static SourceCode Generate(MappingModel model)
        {
            using var builder = new SourceBuilder()
                                .WriteLine(GeneratedFilesHeader)
                                .WriteNullableContextOptionIf(model.Options.SupportNullableReferenceTypes)
                                .WriteUsings(model.Usings)
                                .WriteLine()

                                // Namespace declaration
                                .WriteLine($"namespace {model.Namespace}")
                                .WriteOpeningBracket()

                                // Class declaration
                                .WriteLine($"partial record {model.TypeIdentifierName}")
                                .WriteOpeningBracket();

            // Class body
            if (model.GenerateSecondaryConstructor)
            {
                builder
                .GenerateSecondaryConstructor(model)
                .WriteLine();
            }

            builder
            .GeneratePrivateConstructor(model)
            .WriteLine()
            .GenerateFactoryMethod(model)

            // End class declaration
            .WriteClosingBracket()
            .WriteLine()

            // Extension class declaration
            .GenerateSourceTypeExtensionClass(model)

            // End namespace declaration
            .WriteClosingBracket();

            return(new(builder.ToString(), $"{model.Namespace}.{model.TypeIdentifierName}.g.cs"));
        }
Exemple #5
0
        internal static SourceCode Generate(SourceGenerationOptions options)
        {
            var builder = new SourceBuilder()
                          .WriteLine(GeneratedFilesHeader)
                          .WriteLine("using System;")
                          .WriteLine()
                          .WriteLine($"namespace {RootNamespace}")
                          .WriteOpeningBracket();

            if (options.GenerateXmlDocument)
            {
                builder
                .WriteLine("/// <summary>")
                .WriteLine("/// Specifies that the annotated property should be excluded.")
                .WriteLine("/// </summary>");
            }

            builder
            .WriteLine("[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]")
            .WriteLine($"public sealed class {AttributeClassName} : Attribute {{ }}")
            .WriteClosingBracket();

            return(new(builder.ToString(), $"{AttributeClassName}.g.cs"));
        }
        internal static SourceCode Generate(SourceGenerationOptions options)
        {
            var usings = new List <string> {
                "System", "System.Collections.Generic", "System.Reflection"
            };

            using var builder = new SourceBuilder()
                                .WriteLine(GeneratedFilesHeader)
                                .WriteLine()
                                .WriteUsings(usings)
                                .WriteLine()

                                // Namespace declaration
                                .WriteLine($"namespace {RootNamespace}")
                                .WriteOpeningBracket()

                                // Class declaration
                                .WriteLine($"internal sealed class {ClassName}")
                                .WriteOpeningBracket()

                                .WriteLine("private readonly Dictionary<object, object> _cache;")
                                .WriteLine()

                                // Constructor
                                .WriteLine($"internal {ClassName}()")
                                .WriteOpeningBracket()
                                .WriteLine("_cache = new Dictionary<object, object>(1);")
                                .WriteClosingBracket()
                                .WriteLine()

                                // Factory
                                .WriteLine($"internal static TMapped {FactoryMethodName}<TOriginal, TMapped>(TOriginal original)")
                                .WriteOpeningBracket()
                                .WriteLine("if (original == null) throw new ArgumentNullException(nameof(original));")
                                .WriteLine()
                                .WriteLine("var context = new MappingContext();")
                                .WriteLine("var mapped = context.MapFromWithContext<TOriginal, TMapped>(original);")
                                .WriteLine()
                                .WriteLine("if (mapped == null)")
                                .WriteOpeningBracket()
                                .WriteLine("throw new InvalidOperationException();")
                                .WriteClosingBracket()
                                .WriteLine()
                                .WriteLine("return mapped;")
                                .WriteClosingBracket()
                                .WriteLine()

                                // MapFromWithContext method
                                .WriteLine($"internal TMapped MapFromWithContext<TOriginal, TMapped>(TOriginal original)")
                                .WriteOpeningBracket()
                                .WriteLine("if (original == null)")
                                .WriteOpeningBracket()
                                .WriteLine("return default(TMapped);")
                                .WriteClosingBracket()
                                .WriteLine()
                                .WriteLine("if (!TryGetValue<TOriginal, TMapped>(original, out var mapped))")
                                .WriteOpeningBracket()
                                .WriteLine("var instance = Activator.CreateInstance(typeof(TMapped), BindingFlags.Instance | BindingFlags.NonPublic, null, new object[] { this, original }, null);")
                                .WriteLine("if (instance != null)")
                                .WriteOpeningBracket()
                                .WriteLine("mapped = (TMapped)instance;")
                                .WriteClosingBracket()
                                .WriteClosingBracket()
                                .WriteLine()
                                .WriteLine("return mapped;")
                                .WriteClosingBracket()
                                .WriteLine()

                                // Register method
                                .WriteLine("internal void Register<TOriginal, TMapped>(TOriginal original, TMapped mapped)")
                                .WriteOpeningBracket()
                                .WriteLine("if (original == null) throw new ArgumentNullException(nameof(original));")
                                .WriteLine("if (mapped == null) throw new ArgumentNullException(nameof(mapped));")
                                .WriteLine()
                                .WriteLine("if (!_cache.ContainsKey(original))")
                                .WriteOpeningBracket()
                                .WriteLine("_cache.Add(original, mapped);")
                                .WriteClosingBracket()
                                .WriteClosingBracket()
                                .WriteLine()

                                // TryGetValue method
                                .WriteLine("private bool TryGetValue<TOriginal, TMapped>(TOriginal original, out TMapped mapped)")
                                .WriteOpeningBracket()
                                .WriteLine("if (original != null && _cache.TryGetValue(original, out var value))")
                                .WriteOpeningBracket()
                                .WriteLine("mapped = (TMapped)value;")
                                .WriteLine("return true;")
                                .WriteClosingBracket()
                                .WriteLine()
                                .WriteLine("mapped = default(TMapped);")
                                .WriteLine("return false;")
                                .WriteClosingBracket()

                                // End class declaration
                                .WriteClosingBracket()

                                // End namespace declaration
                                .WriteClosingBracket();

            return(new(builder.ToString(), $"{ClassName}.g.cs"));
        }
        internal static SourceCode Generate(SourceGenerationOptions options)
        {
            using var builder = new SourceBuilder()
                                .WriteLine(GeneratedFilesHeader)
                                .WriteNullableContextOptionIf(options.SupportNullableReferenceTypes)
                                .WriteLine()
                                .WriteLine("using System;")
                                .WriteLine()
                                .WriteLine($"namespace {RootNamespace}")
                                .WriteOpeningBracket();

            if (options.GenerateXmlDocument)
            {
                builder
                .WriteLine("/// <summary>")
                .WriteLine("/// Specifies what type to use as a converter for the property this attribute is bound to.")
                .WriteLine("/// </summary>");
            }

            builder
            .WriteLine("[AttributeUsage(AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false)]")
            .WriteLine($"public sealed class {AttributeClassName} : Attribute")
            .WriteOpeningBracket();

            if (options.GenerateXmlDocument)
            {
                builder
                .WriteLine("/// <summary>")
                .WriteLine($"/// Initializes a new instance of <see cref=\"{AttributeClassName}\"/>.")
                .WriteLine("/// </summary>")
                .WriteLine($"/// <param name=\"converter\">The <see cref=\"{ITypeConverterSource.InterfaceName}{{TSource,TDestination}}\" /> to be used to convert the source type.</param>")
                .WriteLine("/// <param name=\"converterParameters\">The list of parameters to pass to the <paramref name=\"converter\"/> during the type conversion.</param>");
            }

            builder
            .WriteLine($"public {AttributeClassName}(Type converter, object[]{options.NullableReferenceSyntax} converterParameters = null)")
            .WriteOpeningBracket()
            .WriteLine($"{ConverterPropertyName} = converter;")
            .WriteLine($"{ConverterParametersPropertyName} = converterParameters;")
            .WriteClosingBracket()
            .WriteLine();

            if (options.GenerateXmlDocument)
            {
                builder
                .WriteLine("/// <summary>")
                .WriteLine($"/// Gets or sets the <see cref=\"{ITypeConverterSource.InterfaceName}{{TSource,TDestination}}\" /> to be used to convert the source type.")
                .WriteLine("/// </summary>");
            }

            builder
            .WriteLine($"public Type {ConverterPropertyName} {{ get; }}")
            .WriteLine();

            if (options.GenerateXmlDocument)
            {
                builder
                .WriteLine("/// <summary>")
                .WriteLine($"/// Gets the list of parameters to pass to the <see cref=\"{ConverterPropertyName}\"/> during the type conversion.")
                .WriteLine("/// </summary>");
            }

            builder
            .WriteLine($"public object[]{options.NullableReferenceSyntax} {ConverterParametersPropertyName} {{ get; }}")
            .WriteClosingBracket()
            .WriteClosingBracket();

            return(new(builder.ToString(), $"{AttributeClassName}.g.cs"));
        }