Category: RSCG

RSCG – CodeAnalysis

RSCG – CodeAnalysis
 
 

name CodeAnalysis
nuget https://www.nuget.org/packages/Feast.CodeAnalysis/
link https://github.com/feast107/CodeAnalysis
author Feast

Code to string literal. Unfortunately, it carries also some other CodeAnalysis generated files, which are not so useful.

 

This is how you can use CodeAnalysis .

The code that you start with is


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Feast.CodeAnalysis" Version="0.1.4" />
	  <PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4">
		  <PrivateAssets>all</PrivateAssets>
		  <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
	  </PackageReference>
	  <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.0.1" />
  </ItemGroup>
	<PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
	</PropertyGroup>
</Project>


The code that you will use is


Console.WriteLine(Namespace_Andrei.Class_Ignat.Text);

 

The code that is generated is

using System;
using System.Linq;

namespace Microsoft.CodeAnalysis
{
    public static class AttributeDataExtensions
    {
        internal static T ToAttribute<T>(this global::Microsoft.CodeAnalysis.AttributeData attributeData)
            where T : global::System.Attribute
        {
            if (attributeData.AttributeConstructor == null)
                throw new global::System.ArgumentException("Attribute constructor not found");
            var attrType = typeof(T);
            var ctor = attrType.GetConstructors().FirstOrDefault(x =>
            {
                var param = x.GetParameters();
                if (param.Length != attributeData.AttributeConstructor.Parameters.Length)
                    return false;
                return !param.Where((t, i) => attributeData.AttributeConstructor.Parameters[i].Type.ToType().FullName != t.ParameterType.FullName).Any();
            });
            if (ctor == null)
                throw new global::System.MissingMethodException("Cannot find best match ctor for attribute");
            var param = ctor.GetParameters();
            var args = attributeData.ConstructorArguments.Select((x, i) => x.GetArgumentValue(param[i].ParameterType)).ToArray();
            var attribute = (T)global::System.Activator.CreateInstance(typeof(T), args);
            var publicProps = attrType.GetProperties(global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.Instance).Where(static x => x.CanWrite).ToDictionary(static x => x.Name, static x => x);
            foreach (var argument in attributeData.NamedArguments)
            {
                if (!publicProps.TryGetValue(argument.Key, out var prop))
                    continue;
                prop.SetValue(attribute, argument.Value.GetArgumentValue(prop.PropertyType));
            }

            return attribute;
        }
    }
}
using System;
using System.Linq;
using Microsoft.CodeAnalysis;

namespace Feast.CodeAnalysis.CompileTime
{
    internal partial class Assembly(global::Microsoft.CodeAnalysis.IAssemblySymbol symbol) : global::System.Reflection.Assembly, global::System.IEquatable<global::System.Reflection.Assembly>
    {
        internal readonly global::Microsoft.CodeAnalysis.IAssemblySymbol Symbol = symbol;
        public override string FullName => Symbol.GetFullyQualifiedName();
        public override string Location => Symbol.Locations.FirstOrDefault()?.GetLineSpan().Path ?? string.Empty;
        public override bool ReflectionOnly => !Symbol.CanBeReferencedByName;
        public override global::System.Collections.Generic.IEnumerable<global::System.Reflection.Module> Modules => Symbol.Modules.Select(static x => new global::Feast.CodeAnalysis.CompileTime.Module(x));
        public override global::System.Collections.Generic.IEnumerable<global::System.Type> ExportedTypes => Symbol.GetForwardedTypes().Where(static x => x.DeclaredAccessibility == global::Microsoft.CodeAnalysis.Accessibility.Public).Select(static x => new global::Feast.CodeAnalysis.CompileTime.Type(x));

        public bool Equals(global::System.Reflection.Assembly other)
        {
            if (other is global::Feast.CodeAnalysis.CompileTime.Assembly compileTime)
                return global::Microsoft.CodeAnalysis.SymbolEqualityComparer.Default.Equals(Symbol, compileTime.Symbol);
            return other is not null && FullName == other.FullName;
        }

        public override int GetHashCode() => Symbol.GetHashCode();
        public override bool Equals(object o) => o is global::Feast.CodeAnalysis.CompileTime.Assembly assembly && Equals(assembly);
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Metadata;
using Microsoft.CodeAnalysis;

namespace Feast.CodeAnalysis.CompileTime
{
    public partial class AttributeData(global::Microsoft.CodeAnalysis.AttributeData attributeData) : global::System.Reflection.CustomAttributeData
    {
        public override global::System.Reflection.ConstructorInfo Constructor => new global::Feast.CodeAnalysis.CompileTime.ConstructorInfo(attributeData.AttributeConstructor!);
        public override global::System.Collections.Generic.IList<global::System.Reflection.CustomAttributeTypedArgument> ConstructorArguments => attributeData.ConstructorArguments.Select((x, i) =>
        {
            var value = x.GetArgumentValue();
            return new CustomAttributeTypedArgument(attributeData.AttributeConstructor!.Parameters[i].Type.ToType(), value);
        }).ToList();
        public override global::System.Collections.Generic.IList<global::System.Reflection.CustomAttributeNamedArgument> NamedArguments => attributeData.NamedArguments.Select(x =>
        {
            var value = x.Value.GetArgumentValue();
            if (value is null)
                return (global::System.Reflection.CustomAttributeNamedArgument? )null;
            return new global::System.Reflection.CustomAttributeNamedArgument(attributeData.AttributeClass!.GetMembers().First(p => p.Name == x.Key).ToMemberInfo(), value);
        }).Where(static x => x != null).Cast<global::System.Reflection.CustomAttributeNamedArgument>().ToList();
    }
}
using System;
using System.Reflection;

namespace Microsoft.CodeAnalysis
{
    public static partial class CompileTimeExtensions
    {
        public static global::System.Reflection.Assembly ToAssembly(this global::Microsoft.CodeAnalysis.IAssemblySymbol symbol) => new global::Feast.CodeAnalysis.CompileTime.Assembly(symbol);
        public static global::System.Reflection.Module ToModule(this global::Microsoft.CodeAnalysis.IModuleSymbol symbol) => new global::Feast.CodeAnalysis.CompileTime.Module(symbol);
        public static global::System.Type ToType(this global::Microsoft.CodeAnalysis.ITypeSymbol symbol) => new global::Feast.CodeAnalysis.CompileTime.Type(symbol);
        public static global::System.Reflection.MemberInfo ToMemberInfo(this global::Microsoft.CodeAnalysis.ISymbol symbol) => new global::Feast.CodeAnalysis.CompileTime.MemberInfo(symbol);
        public static global::System.Reflection.MethodInfo ToMethodInfo(this global::Microsoft.CodeAnalysis.IMethodSymbol symbol) => new global::Feast.CodeAnalysis.CompileTime.MethodInfo(symbol);
        public static global::System.Reflection.FieldInfo ToFieldInfo(this global::Microsoft.CodeAnalysis.IFieldSymbol symbol) => new global::Feast.CodeAnalysis.CompileTime.FieldInfo(symbol);
        public static global::System.Reflection.PropertyInfo ToPropertyInfo(this global::Microsoft.CodeAnalysis.IPropertySymbol symbol) => new global::Feast.CodeAnalysis.CompileTime.PropertyInfo(symbol);
        public static global::System.Reflection.ConstructorInfo ToConstructorInfo(this global::Microsoft.CodeAnalysis.IMethodSymbol symbol) => new global::Feast.CodeAnalysis.CompileTime.ConstructorInfo(symbol);
        public static global::System.Reflection.EventInfo ToEventInfo(this global::Microsoft.CodeAnalysis.IEventSymbol symbol) => new global::Feast.CodeAnalysis.CompileTime.EventInfo(symbol);
        public static global::System.Reflection.ParameterInfo ToParameterInfo(this global::Microsoft.CodeAnalysis.IParameterSymbol symbol) => new global::Feast.CodeAnalysis.CompileTime.ParameterInfo(symbol);
        public static bool IsAssignableTo(this global::System.Type type, global::System.Type another) => another.IsAssignableFrom(type);
    }
}
using System;
using System.Linq;
using System.Reflection;

namespace Feast.CodeAnalysis.CompileTime
{
    internal partial class ConstructorInfo(global::Microsoft.CodeAnalysis.IMethodSymbol constructor) : global::System.Reflection.ConstructorInfo
    {
        public override object[] GetCustomAttributes(bool inherit) => constructor.GetAttributes().CastArray<object>().ToArray();
        public override object[] GetCustomAttributes(global::System.Type attributeType, bool inherit) => constructor.GetAttributes().Where(x => x.AttributeClass?.ToDisplayString() == attributeType.FullName).Cast<object>().ToArray();
        public override bool IsDefined(global::System.Type attributeType, bool inherit) => constructor.GetAttributes().Any(x => x.AttributeClass?.ToDisplayString() == attributeType.FullName);
        public override global::System.Type DeclaringType => new global::Feast.CodeAnalysis.CompileTime.Type((constructor.ContainingSymbol as global::Microsoft.CodeAnalysis.ITypeSymbol)!);
        public override string Name => constructor.MetadataName;
        public override global::System.Type ReflectedType => new global::Feast.CodeAnalysis.CompileTime.Type(constructor.ReturnType);

        public override global::System.Reflection.MethodImplAttributes GetMethodImplementationFlags() => throw new global::System.NotSupportedException();
        public override global::System.Reflection.ParameterInfo[] GetParameters() => constructor.Parameters.Select(static x => (global::System.Reflection.ParameterInfo)new global::Feast.CodeAnalysis.CompileTime.ParameterInfo(x)).ToArray();
        public override object Invoke(object obj, global::System.Reflection.BindingFlags invokeAttr, global::System.Reflection.Binder binder, object[] parameters, global::System.Globalization.CultureInfo culture) => throw new global::System.NotSupportedException();
        public override global::System.Reflection.MethodAttributes Attributes
        {
            get
            {
                var ret = global::System.Reflection.MethodAttributes.PrivateScope;
                if (constructor.IsStatic)
                    ret |= global::System.Reflection.MethodAttributes.Static;
                if (constructor.IsVirtual)
                    ret |= global::System.Reflection.MethodAttributes.Virtual;
                if (constructor.IsAbstract)
                    ret |= global::System.Reflection.MethodAttributes.Abstract;
                switch (constructor.DeclaredAccessibility)
                {
                    case global::Microsoft.CodeAnalysis.Accessibility.Public:
                        ret |= global::System.Reflection.MethodAttributes.Public;
                        break;
                    case Microsoft.CodeAnalysis.Accessibility.Protected or Microsoft.CodeAnalysis.Accessibility.Private:
                        ret |= global::System.Reflection.MethodAttributes.Private;
                        break;
                }

                return ret;
            }
        }

        public override global::System.RuntimeMethodHandle MethodHandle => throw new global::System.NotSupportedException();

        public override object Invoke(global::System.Reflection.BindingFlags invokeAttr, global::System.Reflection.Binder binder, object[] parameters, global::System.Globalization.CultureInfo culture) => throw new global::System.NotSupportedException();
    }
}
using System;
using System.Linq;

namespace Feast.CodeAnalysis.CompileTime
{
    internal partial class EventInfo(global::Microsoft.CodeAnalysis.IEventSymbol @event) : global::System.Reflection.EventInfo
    {
        public override object[] GetCustomAttributes(bool inherit) => @event.GetAttributes().CastArray<object>().ToArray();
        public override object[] GetCustomAttributes(global::System.Type attributeType, bool inherit) => @event.GetAttributes().Where(x => x.AttributeClass?.ToDisplayString() == attributeType.FullName).Cast<object>().ToArray();
        public override bool IsDefined(global::System.Type attributeType, bool inherit) => @event.GetAttributes().Any(x => x.AttributeClass?.ToDisplayString() == attributeType.FullName);
        public override global::System.Type DeclaringType => new global::Feast.CodeAnalysis.CompileTime.Type((@event.ContainingSymbol as global::Microsoft.CodeAnalysis.ITypeSymbol)!);
        public override string Name => @event.MetadataName;
        public override global::System.Type ReflectedType => DeclaringType;

        public override global::System.Reflection.MethodInfo GetAddMethod(bool nonPublic) => @event.AddMethod == null ? null : @event.AddMethod.DeclaredAccessibility != global::Microsoft.CodeAnalysis.Accessibility.Public == nonPublic ? new global::Feast.CodeAnalysis.CompileTime.MethodInfo(@event.AddMethod) : null;
        public override global::System.Reflection.MethodInfo GetRaiseMethod(bool nonPublic) => @event.RaiseMethod == null ? null : @event.RaiseMethod.DeclaredAccessibility != global::Microsoft.CodeAnalysis.Accessibility.Public == nonPublic ? new global::Feast.CodeAnalysis.CompileTime.MethodInfo(@event.RaiseMethod) : null;
        public override global::System.Reflection.MethodInfo GetRemoveMethod(bool nonPublic) => @event.RemoveMethod == null ? null : @event.RemoveMethod.DeclaredAccessibility != global::Microsoft.CodeAnalysis.Accessibility.Public == nonPublic ? new global::Feast.CodeAnalysis.CompileTime.MethodInfo(@event.RemoveMethod) : null;
        public override global::System.Reflection.EventAttributes Attributes => global::System.Reflection.EventAttributes.None;
    }
}
using System;
using System.Linq;

namespace Feast.CodeAnalysis.CompileTime
{
    internal partial class FieldInfo(global::Microsoft.CodeAnalysis.IFieldSymbol field) : global::System.Reflection.FieldInfo
    {
        public override object[] GetCustomAttributes(bool inherit) => field.GetAttributes().CastArray<object>().ToArray();
        public override object[] GetCustomAttributes(global::System.Type attributeType, bool inherit) => field.GetAttributes().Where(x => x.AttributeClass?.ToDisplayString() == attributeType.FullName).Cast<object>().ToArray();
        public override bool IsDefined(global::System.Type attributeType, bool inherit) => field.GetAttributes().Any(x => x.AttributeClass?.ToDisplayString() == attributeType.FullName);
        public override global::System.Type DeclaringType => new global::Feast.CodeAnalysis.CompileTime.Type(field.ContainingType);
        public override string Name => field.MetadataName;
        public override global::System.Type ReflectedType => FieldType;

        public override object GetValue(object obj) => throw new global::System.NotSupportedException();
        public override void SetValue(object obj, object value, global::System.Reflection.BindingFlags invokeAttr, global::System.Reflection.Binder binder, global::System.Globalization.CultureInfo culture) => throw new global::System.NotSupportedException();
        public override global::System.Reflection.FieldAttributes Attributes
        {
            get
            {
                var ret = global::System.Reflection.FieldAttributes.PrivateScope;
                if (field.IsStatic)
                    ret |= global::System.Reflection.FieldAttributes.Static;
                if (field.IsReadOnly)
                    ret |= global::System.Reflection.FieldAttributes.InitOnly;
                if (field.HasConstantValue)
                    ret |= global::System.Reflection.FieldAttributes.HasDefault;
                if (field.IsConst)
                    ret |= global::System.Reflection.FieldAttributes.Literal;
                switch (field.DeclaredAccessibility)
                {
                    case global::Microsoft.CodeAnalysis.Accessibility.Public:
                        ret |= global::System.Reflection.FieldAttributes.Public;
                        break;
                    default:
                        ret |= global::System.Reflection.FieldAttributes.Private;
                        break;
                }

                return ret;
            }
        }

        public override global::System.RuntimeFieldHandle FieldHandle => throw new global::System.NotSupportedException();
        public override global::System.Type FieldType => new global::Feast.CodeAnalysis.CompileTime.Type(field.Type);
    }
}
using System;
using System.Linq;

namespace Feast.CodeAnalysis.CompileTime
{
    internal partial class MemberInfo(global::Microsoft.CodeAnalysis.ISymbol symbol) : global::System.Reflection.MemberInfo
    {
        public override object[] GetCustomAttributes(bool inherit) => symbol.GetAttributes().CastArray<object>().ToArray();
        public override object[] GetCustomAttributes(global::System.Type attributeType, bool inherit) => symbol.GetAttributes().Where(x => x.AttributeClass?.ToDisplayString() == attributeType.FullName).Cast<object>().ToArray();
        public override bool IsDefined(global::System.Type attributeType, bool inherit) => symbol.GetAttributes().Any(x => x.AttributeClass?.ToDisplayString() == attributeType.FullName);
        public override global::System.Type DeclaringType => new global::Feast.CodeAnalysis.CompileTime.Type(symbol.ContainingType);

        public override global::System.Reflection.MemberTypes MemberType
        {
            get
            {
                return symbol switch
                {
                    global::Microsoft.CodeAnalysis.ITypeSymbol type => type.ContainingType != null ? global::System.Reflection.MemberTypes.NestedType : global::System.Reflection.MemberTypes.TypeInfo,
                    global::Microsoft.CodeAnalysis.IPropertySymbol => global::System.Reflection.MemberTypes.Property,
                    global::Microsoft.CodeAnalysis.IFieldSymbol => global::System.Reflection.MemberTypes.Field,
                    global::Microsoft.CodeAnalysis.IMethodSymbol method => method.ContainingType.Constructors.Contains(method) ? global::System.Reflection.MemberTypes.Constructor : global::System.Reflection.MemberTypes.Method,
                    global::Microsoft.CodeAnalysis.IEventSymbol => global::System.Reflection.MemberTypes.Event,
                    _ => global::System.Reflection.MemberTypes.Custom
                };
            }
        }

        public override string Name => symbol.MetadataName;
        public override global::System.Type ReflectedType => new global::Feast.CodeAnalysis.CompileTime.Type(symbol switch
        {
            global::Microsoft.CodeAnalysis.ITypeSymbol type => type,
            global::Microsoft.CodeAnalysis.IPropertySymbol property => property.Type,
            global::Microsoft.CodeAnalysis.IFieldSymbol field => field.Type,
            global::Microsoft.CodeAnalysis.IMethodSymbol method => method.ReturnType,
            _ => throw new global::System.ArgumentOutOfRangeException()});
    }
}
using System;
using System.Linq;

namespace Feast.CodeAnalysis.CompileTime
{
    internal partial class MethodInfo(global::Microsoft.CodeAnalysis.IMethodSymbol method) : global::System.Reflection.MethodInfo
    {
        public override object[] GetCustomAttributes(bool inherit) => method.GetAttributes().CastArray<object>().ToArray();
        public override object[] GetCustomAttributes(global::System.Type attributeType, bool inherit) => method.GetAttributes().Where(x => x.AttributeClass?.ToDisplayString() == attributeType.FullName).Cast<object>().ToArray();
        public override bool IsDefined(global::System.Type attributeType, bool inherit) => method.GetAttributes().Any(x => x.AttributeClass?.ToDisplayString() == attributeType.FullName);
        public override global::System.Type DeclaringType => new global::Feast.CodeAnalysis.CompileTime.Type((method.ContainingSymbol as global::Microsoft.CodeAnalysis.ITypeSymbol)!);
        public override string Name => method.MetadataName;
        public override global::System.Type ReflectedType => new global::Feast.CodeAnalysis.CompileTime.Type(method.ReturnType);

        public override global::System.Reflection.MethodImplAttributes GetMethodImplementationFlags()
        {
            var ret = global::System.Reflection.MethodImplAttributes.Managed;
            return ret;
        }

        public override global::System.Reflection.ParameterInfo[] GetParameters() => method.Parameters.Select(static x => (global::System.Reflection.ParameterInfo)new global::Feast.CodeAnalysis.CompileTime.ParameterInfo(x)).ToArray();
        public override object Invoke(object obj, global::System.Reflection.BindingFlags invokeAttr, global::System.Reflection.Binder binder, object[] parameters, global::System.Globalization.CultureInfo culture) => throw new global::System.NotSupportedException();
        public override global::System.Reflection.MethodAttributes Attributes
        {
            get
            {
                var ret = global::System.Reflection.MethodAttributes.PrivateScope;
                if (method.IsStatic)
                    ret |= global::System.Reflection.MethodAttributes.Static;
                if (method.IsVirtual)
                    ret |= global::System.Reflection.MethodAttributes.Virtual;
                if (method.IsAbstract)
                    ret |= global::System.Reflection.MethodAttributes.Abstract;
                switch (method.DeclaredAccessibility)
                {
                    case global::Microsoft.CodeAnalysis.Accessibility.Public:
                        ret |= global::System.Reflection.MethodAttributes.Public;
                        break;
                    case Microsoft.CodeAnalysis.Accessibility.Protected or Microsoft.CodeAnalysis.Accessibility.Private:
                        ret |= global::System.Reflection.MethodAttributes.Private;
                        break;
                }

                return ret;
            }
        }

        public override global::System.RuntimeMethodHandle MethodHandle => throw new global::System.NotSupportedException();

        public override global::System.Reflection.MethodInfo GetBaseDefinition() => new global::Feast.CodeAnalysis.CompileTime.MethodInfo(method.OriginalDefinition);
        public override global::System.Reflection.ICustomAttributeProvider ReturnTypeCustomAttributes => throw new global::System.NotImplementedException();
    }
}
using System;
using Microsoft.CodeAnalysis;

namespace Feast.CodeAnalysis.CompileTime
{
    internal partial class Module(global::Microsoft.CodeAnalysis.IModuleSymbol module) : global::System.Reflection.Module
    {
        public override string Name => module.MetadataName;
        public override string FullyQualifiedName => module.GetFullyQualifiedName();
        public override global::System.Reflection.Assembly Assembly => new global::Feast.CodeAnalysis.CompileTime.Assembly(module.ContainingAssembly);
    }
}
using System;

namespace Feast.CodeAnalysis.CompileTime
{
    internal partial class ParameterInfo(global::Microsoft.CodeAnalysis.IParameterSymbol parameter) : global::System.Reflection.ParameterInfo
    {
        public override string Name => parameter.MetadataName;
        public override global::System.Type ParameterType => new global::Feast.CodeAnalysis.CompileTime.Type(parameter.Type);

        public override global::System.Reflection.ParameterAttributes Attributes
        {
            get
            {
                var ret = global::System.Reflection.ParameterAttributes.None;
                if (parameter.IsOptional)
                    ret |= global::System.Reflection.ParameterAttributes.Optional;
                switch (parameter.RefKind)
                {
                    case global::Microsoft.CodeAnalysis.RefKind.Out:
                        ret |= global::System.Reflection.ParameterAttributes.Out;
                        break;
                    case global::Microsoft.CodeAnalysis.RefKind.In:
                        ret |= global::System.Reflection.ParameterAttributes.In;
                        break;
                }

                return ret;
            }
        }

        public override object DefaultValue => parameter.ExplicitDefaultValue;
    }
}
using System;
using System.Linq;
using Microsoft.CodeAnalysis;

namespace Feast.CodeAnalysis.CompileTime
{
    internal partial class PropertyInfo(global::Microsoft.CodeAnalysis.IPropertySymbol property) : global::System.Reflection.PropertyInfo
    {
        public override object[] GetCustomAttributes(bool inherit) => property.GetAttributes().Cast<object>().ToArray();
        public override object[] GetCustomAttributes(global::System.Type attributeType, bool inherit) => property.GetAttributes().Where(x => x.AttributeClass?.ToDisplayString() == attributeType.FullName).Cast<object>().ToArray();
        public override bool IsDefined(global::System.Type attributeType, bool inherit) => property.GetAttributes().Any(x => x.AttributeClass?.ToDisplayString() == attributeType.FullName);
        public override global::System.Type DeclaringType => new global::Feast.CodeAnalysis.CompileTime.Type(property.ContainingType);
        public override string Name => property.Name;
        public override global::System.Type ReflectedType => PropertyType;

        public override global::System.Reflection.MethodInfo[] GetAccessors(bool nonPublic) => [GetGetMethod(nonPublic), GetSetMethod(nonPublic)];
        public override global::System.Reflection.MethodInfo GetGetMethod(bool nonPublic) => property.GetMethod == null ? null : property.GetMethod.DeclaredAccessibility != global::Microsoft.CodeAnalysis.Accessibility.Public == nonPublic ? new global::Feast.CodeAnalysis.CompileTime.MethodInfo(property.GetMethod) : null;
        public override global::System.Reflection.ParameterInfo[] GetIndexParameters() => property.Parameters.Select(x => (global::System.Reflection.ParameterInfo)new global::Feast.CodeAnalysis.CompileTime.ParameterInfo(x)).ToArray();
        public override global::System.Reflection.MethodInfo GetSetMethod(bool nonPublic) => property.SetMethod == null ? null : property.SetMethod.DeclaredAccessibility != global::Microsoft.CodeAnalysis.Accessibility.Public == nonPublic ? new global::Feast.CodeAnalysis.CompileTime.MethodInfo(property.SetMethod) : null;
        public override object GetValue(object obj, global::System.Reflection.BindingFlags invokeAttr, global::System.Reflection.Binder binder, object[] index, global::System.Globalization.CultureInfo culture) => throw new global::System.NotSupportedException();
        public override void SetValue(object obj, object value, global::System.Reflection.BindingFlags invokeAttr, global::System.Reflection.Binder binder, object[] index, global::System.Globalization.CultureInfo culture) => throw new global::System.NotSupportedException();
        public override global::System.Reflection.PropertyAttributes Attributes => global::System.Reflection.PropertyAttributes.SpecialName;
        public override bool CanRead => !property.IsWriteOnly;
        public override bool CanWrite => !property.IsReadOnly;
        public override global::System.Reflection.Module Module => property.ContainingModule.ToModule();
        public override global::System.Type PropertyType => new global::Feast.CodeAnalysis.CompileTime.Type(property.Type);
    }
}
using System;
using System.Linq;
using System.Reflection;
using Microsoft.CodeAnalysis;

namespace Feast.CodeAnalysis.CompileTime
{
    internal partial class Type(global::Microsoft.CodeAnalysis.ITypeSymbol symbol) : global::System.Type, global::System.IEquatable<global::System.Type>
    {
        internal readonly global::Microsoft.CodeAnalysis.ITypeSymbol Symbol = symbol;
        public override object[] GetCustomAttributes(bool inherit) => Symbol.GetAttributes().CastArray<object>().ToArray();
        public override object[] GetCustomAttributes(global::System.Type attributeType, bool inherit) => Symbol.GetAttributes().Where(x => x.AttributeClass?.ToDisplayString() == attributeType.FullName).Cast<object>().ToArray();
        public override bool IsDefined(global::System.Type attributeType, bool inherit) => Symbol.GetAttributes().Any(x => x.AttributeClass?.ToDisplayString() == attributeType.FullName);
        public override global::System.Collections.Generic.IEnumerable<global::System.Reflection.CustomAttributeData> CustomAttributes => Symbol.GetAttributes().Select(x => new global::Feast.CodeAnalysis.CompileTime.AttributeData(x));
        public override string Namespace => Symbol.ContainingNamespace.ToDisplayString();
        public override string Name => Symbol.MetadataName;
        public override string FullName => Symbol.TypeKind switch
        {
            global::Microsoft.CodeAnalysis.TypeKind.Array => $"{GetElementType()!.FullName}[]",
            global::Microsoft.CodeAnalysis.TypeKind.Pointer => $"{GetElementType()!.FullName}*",
            _ => $"{Namespace}.{Name}{(!IsGenericType ? string.Empty : '[' + string.Join(",", GenericTypeArguments.Select(x => $"[{x.AssemblyQualifiedName}]")) + ']')}"};
        public override string AssemblyQualifiedName => $"{FullName}, {Assembly.FullName}";
        public override global::System.Guid GUID => throw new global::System.NotSupportedException();
        public override global::System.Reflection.MemberTypes MemberType => Symbol.ContainingType is not null ? global::System.Reflection.MemberTypes.NestedType : global::System.Reflection.MemberTypes.TypeInfo;
        public override global::System.Type BaseType => Symbol.BaseType == null ? null : new global::Feast.CodeAnalysis.CompileTime.Type(Symbol.BaseType);
        public override global::System.Type ReflectedType => Symbol.ContainingType is null ? null : new global::Feast.CodeAnalysis.CompileTime.Type(Symbol.ContainingType);
        public override global::System.Type DeclaringType => Symbol.ContainingType is null ? null : new global::Feast.CodeAnalysis.CompileTime.Type(Symbol.ContainingType);
        public override global::System.Reflection.MethodBase DeclaringMethod => Symbol.ContainingSymbol is not IMethodSymbol methodSymbol ? null : new global::Feast.CodeAnalysis.CompileTime.MethodInfo(methodSymbol);
        public override bool IsEnum => Symbol.TypeKind == global::Microsoft.CodeAnalysis.TypeKind.Enum;
        public override global::System.Reflection.Assembly Assembly => new global::Feast.CodeAnalysis.CompileTime.Assembly(Symbol.ContainingAssembly);
        public override global::System.Reflection.Module Module => new global::Feast.CodeAnalysis.CompileTime.Module(Symbol.ContainingModule);
        public override global::System.Type UnderlyingSystemType => new global::Feast.CodeAnalysis.CompileTime.Type(Symbol);
        public override bool IsGenericType => Symbol is INamedTypeSymbol { TypeArguments.Length: > 0 };
        public override bool ContainsGenericParameters => Symbol is INamedTypeSymbol { TypeParameters.Length: > 0 };
        public override bool IsGenericParameter => Symbol.TypeKind == global::Microsoft.CodeAnalysis.TypeKind.TypeParameter;
        public override bool IsGenericTypeDefinition => Symbol is global::Microsoft.CodeAnalysis.INamedTypeSymbol namedType && namedType.TypeParameters.Length > namedType.TypeArguments.Length;
        public override bool IsConstructedGenericType => Symbol is global::Microsoft.CodeAnalysis.INamedTypeSymbol namedType && namedType.TypeParameters.Length == namedType.TypeArguments.Length;
        public override global::System.Type[] GenericTypeArguments => Symbol is INamedTypeSymbol { TypeArguments.Length: > 0 } typeSymbol ? typeSymbol.TypeArguments.Select(static x => (global::System.Type)new global::Feast.CodeAnalysis.CompileTime.Type(x)).ToArray() : global::System.Array.Empty<global::System.Type>();

        public override global::System.Type[] GetGenericParameterConstraints()
        {
            if (Symbol is not ITypeParameterSymbol typeParameterSymbol)
                return global::System.Array.Empty<global::System.Type>();
            return typeParameterSymbol.ConstraintTypes.Select(static x => (global::System.Type)new global::Feast.CodeAnalysis.CompileTime.Type(x)).ToArray();
        }

        protected override global::System.Reflection.TypeAttributes GetAttributeFlagsImpl()
        {
            var ret = Symbol.TypeKind switch
            {
                global::Microsoft.CodeAnalysis.TypeKind.Interface => global::System.Reflection.TypeAttributes.Interface,
                global::Microsoft.CodeAnalysis.TypeKind.Class => global::System.Reflection.TypeAttributes.Class,
                _ => global::System.Reflection.TypeAttributes.NotPublic
            };
            if (Symbol.DeclaredAccessibility == global::Microsoft.CodeAnalysis.Accessibility.Public)
            {
                ret |= global::System.Reflection.TypeAttributes.Public;
                if (Symbol.ContainingType != null)
                {
                    ret |= global::System.Reflection.TypeAttributes.NestedPublic;
                }
            }
            else if (Symbol is { DeclaredAccessibility: Accessibility.Private, ContainingType: not null })
            {
                ret |= TypeAttributes.NestedPrivate;
            }

            if (Symbol.IsAbstract)
            {
                ret |= global::System.Reflection.TypeAttributes.Abstract;
            }

            if (Symbol.IsSealed)
            {
                ret |= global::System.Reflection.TypeAttributes.Sealed;
            }

            return ret;
        }

        protected override global::System.Reflection.ConstructorInfo GetConstructorImpl(global::System.Reflection.BindingFlags bindingAttr, global::System.Reflection.Binder binder, global::System.Reflection.CallingConventions callConvention, global::System.Type[] types, global::System.Reflection.ParameterModifier[] modifiers)
        {
            var ret = Symbol.GetMembers().OfType<global::Microsoft.CodeAnalysis.IMethodSymbol>().FirstOrDefault(x => Qualified(x, bindingAttr) && !types.Where((c, i) => new global::Feast.CodeAnalysis.CompileTime.Type(x.Parameters[i].Type).Equals(c)).Any());
            return ret == null ? null : new global::Feast.CodeAnalysis.CompileTime.ConstructorInfo(ret);
        }

        public override global::System.Reflection.ConstructorInfo[] GetConstructors(global::System.Reflection.BindingFlags bindingAttr)
        {
            switch (Symbol.TypeKind)
            {
                case global::Microsoft.CodeAnalysis.TypeKind.Class:
                case global::Microsoft.CodeAnalysis.TypeKind.Array:
                case global::Microsoft.CodeAnalysis.TypeKind.Delegate:
                case global::Microsoft.CodeAnalysis.TypeKind.Struct:
                    return (Symbol as global::Microsoft.CodeAnalysis.INamedTypeSymbol)!.Constructors.Select(static x => (global::System.Reflection.ConstructorInfo)new global::Feast.CodeAnalysis.CompileTime.ConstructorInfo(x)).ToArray();
            }

            return global::System.Array.Empty<global::System.Reflection.ConstructorInfo>();
        }

        public override global::System.Reflection.EventInfo GetEvent(string name, global::System.Reflection.BindingFlags bindingAttr)
        {
            var ret = Symbol.GetMembers().OfType<global::Microsoft.CodeAnalysis.IEventSymbol>().FirstOrDefault(x => x.Name == name && Qualified(x, bindingAttr));
            return ret == null ? null : new global::Feast.CodeAnalysis.CompileTime.EventInfo(ret);
        }

        public override global::System.Reflection.EventInfo[] GetEvents(global::System.Reflection.BindingFlags bindingAttr)
        {
            return Symbol.GetMembers().OfType<global::Microsoft.CodeAnalysis.IEventSymbol>().Where(x => Qualified(x, bindingAttr)).Select(static x => (global::System.Reflection.EventInfo)new global::Feast.CodeAnalysis.CompileTime.EventInfo(x)).ToArray();
        }

        public override global::System.Reflection.FieldInfo GetField(string name, global::System.Reflection.BindingFlags bindingAttr)
        {
            var ret = Symbol.GetMembers().OfType<global::Microsoft.CodeAnalysis.IFieldSymbol>().FirstOrDefault(x => Qualified(x, bindingAttr) && x.Name == name);
            return ret == null ? null : new global::Feast.CodeAnalysis.CompileTime.FieldInfo(ret);
        }

        public override global::System.Reflection.FieldInfo[] GetFields(global::System.Reflection.BindingFlags bindingAttr) => Symbol.GetMembers().OfType<global::Microsoft.CodeAnalysis.IFieldSymbol>().Where(x => Qualified(x, bindingAttr)).Select(static x => (global::System.Reflection.FieldInfo)new global::Feast.CodeAnalysis.CompileTime.FieldInfo(x)).ToArray();
        private static bool Qualified(global::Microsoft.CodeAnalysis.ISymbol symbol, global::System.Reflection.BindingFlags flags) => (!flags.HasFlag(global::System.Reflection.BindingFlags.Instance) || !symbol.IsStatic) && (!flags.HasFlag(global::System.Reflection.BindingFlags.Static) || symbol.IsStatic) && (!flags.HasFlag(global::System.Reflection.BindingFlags.Public) || symbol.DeclaredAccessibility == global::Microsoft.CodeAnalysis.Accessibility.Public) && (!flags.HasFlag(global::System.Reflection.BindingFlags.NonPublic) || symbol.DeclaredAccessibility != global::Microsoft.CodeAnalysis.Accessibility.Public);
        private static bool Qualified(global::Microsoft.CodeAnalysis.ISymbol symbol, global::System.Reflection.MemberTypes memberTypes) => memberTypes is MemberTypes.All || symbol switch
        {
            global::Microsoft.CodeAnalysis.IFieldSymbol => memberTypes.HasFlag(global::System.Reflection.MemberTypes.Field),
            global::Microsoft.CodeAnalysis.IMethodSymbol method => method.MethodKind == global::Microsoft.CodeAnalysis.MethodKind.Constructor ? memberTypes.HasFlag(global::System.Reflection.MemberTypes.Constructor) : memberTypes.HasFlag(global::System.Reflection.MemberTypes.Method),
            global::Microsoft.CodeAnalysis.IPropertySymbol => memberTypes.HasFlag(global::System.Reflection.MemberTypes.Property),
            global::Microsoft.CodeAnalysis.IEventSymbol => memberTypes.HasFlag(global::System.Reflection.MemberTypes.Event),
            global::Microsoft.CodeAnalysis.INamedTypeSymbol => memberTypes.HasFlag(global::System.Reflection.MemberTypes.NestedType),
            _ => false
        };
        public override global::System.Reflection.MemberInfo[] GetMembers(global::System.Reflection.BindingFlags bindingAttr) => Symbol.GetMembers().OfType<global::Microsoft.CodeAnalysis.ISymbol>().Where(x => Qualified(x, bindingAttr)).Select(static x => (global::System.Reflection.MemberInfo)new global::Feast.CodeAnalysis.CompileTime.MemberInfo(x)).ToArray();
        protected override global::System.Reflection.MethodInfo GetMethodImpl(string name, global::System.Reflection.BindingFlags bindingAttr, global::System.Reflection.Binder binder, global::System.Reflection.CallingConventions callConvention, global::System.Type[] types, global::System.Reflection.ParameterModifier[] modifiers)
        {
            var ret = Symbol.GetMembers().OfType<global::Microsoft.CodeAnalysis.IMethodSymbol>().FirstOrDefault(x => x.Name == name && Qualified(x, bindingAttr) && x.Parameters.Length == types.Length && !x.Parameters.Where((p, i) => types[i] != new global::Feast.CodeAnalysis.CompileTime.Type(p.Type)).Any());
            return ret == null ? null : new global::Feast.CodeAnalysis.CompileTime.MethodInfo(ret);
        }

        public override global::System.Reflection.MethodInfo[] GetMethods(global::System.Reflection.BindingFlags bindingAttr) => Symbol.GetMembers().OfType<global::Microsoft.CodeAnalysis.IMethodSymbol>().Where(x => Qualified(x, bindingAttr)).Select(static x => (global::System.Reflection.MethodInfo)new global::Feast.CodeAnalysis.CompileTime.MethodInfo(x)).ToArray();
        public override global::System.Reflection.PropertyInfo[] GetProperties(global::System.Reflection.BindingFlags bindingAttr) => Symbol.GetMembers().OfType<global::Microsoft.CodeAnalysis.IPropertySymbol>().Where(x => Qualified(x, bindingAttr)).Select(static x => (global::System.Reflection.PropertyInfo)new global::Feast.CodeAnalysis.CompileTime.PropertyInfo(x)).ToArray();
        public override global::System.Reflection.EventInfo[] GetEvents() => Symbol.GetMembers().OfType<global::Microsoft.CodeAnalysis.IEventSymbol>().Select(static x => (global::System.Reflection.EventInfo)new global::Feast.CodeAnalysis.CompileTime.EventInfo(x)).ToArray();
        public override bool IsSerializable => Symbol.GetAttributes().Any(static x => x.AttributeClass?.ToType().Equals(typeof(global::System.SerializableAttribute))is true);

        public override global::System.Reflection.MemberInfo[] GetMember(string name, global::System.Reflection.BindingFlags bindingAttr) => Symbol.GetMembers().Where(x => Qualified(x, bindingAttr)).Select(static x => (global::System.Reflection.MemberInfo)new global::Feast.CodeAnalysis.CompileTime.MemberInfo(x)).ToArray();
        public override global::System.Reflection.MemberInfo[] GetMember(string name, global::System.Reflection.MemberTypes type, global::System.Reflection.BindingFlags bindingAttr) => Symbol.GetMembers().Where(x => x.Name == name && Qualified(x, bindingAttr) && Qualified(x, type)).Select(static x => (global::System.Reflection.MemberInfo)new global::Feast.CodeAnalysis.CompileTime.MemberInfo(x)).ToArray();
        public override bool IsEnumDefined(object value) => IsEnum && Symbol.GetMembers().OfType<global::Microsoft.CodeAnalysis.IFieldSymbol>().Any(x => x.ConstantValue == value);
        public override object InvokeMember(string name, global::System.Reflection.BindingFlags invokeAttr, global::System.Reflection.Binder binder, object target, object[] args, global::System.Reflection.ParameterModifier[] modifiers, global::System.Globalization.CultureInfo culture, string[] namedParameters) => throw new global::System.NotSupportedException();
        protected override bool IsArrayImpl() => Symbol.SpecialType == global::Microsoft.CodeAnalysis.SpecialType.System_Array;
        protected override bool IsByRefImpl() => Symbol.IsReferenceType || Symbol.IsRefLikeType;
        protected override bool IsCOMObjectImpl() => Symbol is INamedTypeSymbol { IsComImport: true };
        protected override bool IsPointerImpl() => Symbol.Kind == global::Microsoft.CodeAnalysis.SymbolKind.PointerType;
        protected override bool IsPrimitiveImpl() => Symbol.SpecialType is >= SpecialType.System_Boolean and <= SpecialType.System_Double or global::Microsoft.CodeAnalysis.SpecialType.System_Object or global::Microsoft.CodeAnalysis.SpecialType.System_String;
        public override global::System.Array GetEnumValues() => IsEnum ? Symbol.GetMembers().OfType<global::Microsoft.CodeAnalysis.IFieldSymbol>().Select(x => x.ConstantValue).ToArray() : throw new global::System.InvalidOperationException();
        public override global::System.Reflection.GenericParameterAttributes GenericParameterAttributes => throw new global::System.InvalidOperationException();

        protected override global::System.Reflection.PropertyInfo GetPropertyImpl(string name, global::System.Reflection.BindingFlags bindingAttr, global::System.Reflection.Binder binder, global::System.Type returnType, global::System.Type[] types, global::System.Reflection.ParameterModifier[] modifiers)
        {
            var ret = Symbol.GetMembers().OfType<global::Microsoft.CodeAnalysis.IPropertySymbol>().FirstOrDefault(x => Qualified(x, bindingAttr) && new global::Feast.CodeAnalysis.CompileTime.Type(x.Type).Equals(returnType));
            return ret == null ? null : new global::Feast.CodeAnalysis.CompileTime.PropertyInfo(ret);
        }

        protected override bool HasElementTypeImpl() => Symbol.TypeKind == global::Microsoft.CodeAnalysis.TypeKind.Array || Symbol.TypeKind == global::Microsoft.CodeAnalysis.TypeKind.Pointer || Symbol.IsReferenceType;
        public override global::System.Type GetElementType() => Symbol switch
        {
            { TypeKind: TypeKind.Array } => new global::Feast.CodeAnalysis.CompileTime.Type(Symbol.Interfaces.First(x => x.TypeArguments.Length == 1).TypeArguments[0]),
            { TypeKind: TypeKind.Pointer } and global::Microsoft.CodeAnalysis.IPointerTypeSymbol pointer => new global::Feast.CodeAnalysis.CompileTime.Type(pointer.PointedAtType),
            { IsReferenceType: true } => this,
            _ => null
        };
        protected override bool IsValueTypeImpl() => Symbol.TypeKind is global::Microsoft.CodeAnalysis.TypeKind.Struct or global::Microsoft.CodeAnalysis.TypeKind.Structure;
        public override global::System.Type GetNestedType(string name, global::System.Reflection.BindingFlags bindingAttr)
        {
            var ret = Symbol.GetMembers().OfType<global::Microsoft.CodeAnalysis.INamedTypeSymbol>().FirstOrDefault(x => x.Name == name && Qualified(x, bindingAttr));
            return ret == null ? null : new global::Feast.CodeAnalysis.CompileTime.Type(ret);
        }

        public override global::System.Type[] GetNestedTypes(global::System.Reflection.BindingFlags bindingAttr) => Symbol.GetMembers().OfType<global::Microsoft.CodeAnalysis.INamedTypeSymbol>().Select(x => (global::System.Type)new global::Feast.CodeAnalysis.CompileTime.Type(x)).ToArray();
        public override global::System.Type GetInterface(string name, bool ignoreCase)
        {
            var ret = Symbol.AllInterfaces.FirstOrDefault(x => ignoreCase ? string.Equals(name, x.Name, global::System.StringComparison.OrdinalIgnoreCase) : name == x.Name);
            return ret == null ? null : new global::Feast.CodeAnalysis.CompileTime.Type(ret);
        }

        public override global::System.Type[] GetInterfaces() => Symbol.AllInterfaces.Select(x => (global::System.Type)new global::Feast.CodeAnalysis.CompileTime.Type(x)).ToArray();
        public override bool Equals(global::System.Type o)
        {
            switch (o)
            {
                case null:
                    return false;
                case Type ct:
                    return global::Microsoft.CodeAnalysis.SymbolEqualityComparer.Default.Equals(ct.Symbol, Symbol);
            }

            if (o.FullName != FullName)
                return false;
            return !IsGenericParameter || DeclaringType?.Equals(o.DeclaringType)is true || DeclaringMethod?.Equals(o.DeclaringMethod)is true;
        }

        public override bool IsAssignableFrom(global::System.Type c)
        {
            if (c is null)
                return false;
            if (Equals(c))
                return true;
            switch (this)
            {
                case { IsClass: true }when c.IsClass:
                    return c.IsSubclassOf(this);
                case { IsInterface: true }when c.IsInterface || c.IsClass:
                    return c.GetInterfaces().Any(Equals);
                case { IsGenericParameter: true }:
                    return true;
            }

            return false;
        }

        public override string ToString() => $"{Namespace}.{Name}{(!IsGenericType ? string.Empty : '[' + string.Join(",", GenericTypeArguments.Select(x => x.FullName)) + ']')}";
    }
}
using System;

namespace Feast.CodeAnalysis
{
    public partial class TypeEqualityComparer : global::System.Collections.Generic.IEqualityComparer<global::System.Type>
    {
        public bool Equals(global::System.Type x, global::System.Type y) => x is global::Feast.CodeAnalysis.CompileTime.Type ? x.Equals(y) : y is global::Feast.CodeAnalysis.CompileTime.Type ? y.Equals(x) : x.Equals(y);
        public int GetHashCode(global::System.Type obj) => obj is global::Feast.CodeAnalysis.CompileTime.Type type ? type.GetHashCode() : obj.GetHashCode();
        public static global::Feast.CodeAnalysis.TypeEqualityComparer Default { get; } = new();
    }
}
#if !ROSLYN_4_3_1_OR_GREATER
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Immutable;

namespace Microsoft.CodeAnalysis.Internal
{
    internal readonly struct GeneratorAttributeSyntaxContext
    {
        /// <summary>
        /// Creates a new <see cref="GeneratorAttributeSyntaxContext"/> instance with the specified parameters.
        /// </summary>
        /// <param name="targetNode">The syntax node the attribute is attached to.</param>
        /// <param name="targetSymbol">The symbol that the attribute is attached to.</param>
        /// <param name="semanticModel">Semantic model for the file that <see cref="TargetNode"/> is contained within.</param>
        /// <param name="attributes">The collection of matching attributes.</param>
        internal GeneratorAttributeSyntaxContext(global::Microsoft.CodeAnalysis.SyntaxNode targetNode, global::Microsoft.CodeAnalysis.ISymbol targetSymbol, global::Microsoft.CodeAnalysis.SemanticModel semanticModel, global::System.Collections.Immutable.ImmutableArray<global::Microsoft.CodeAnalysis.AttributeData> attributes)
        {
            TargetNode = targetNode;
            TargetSymbol = targetSymbol;
            SemanticModel = semanticModel;
            Attributes = attributes;
        }

        /// <summary>
        /// The syntax node the attribute is attached to. For example, with <c>[CLSCompliant] class C { }</c> this would the class declaration node.
        /// </summary>
        public global::Microsoft.CodeAnalysis.SyntaxNode TargetNode { get; }
        /// <summary>
        /// The symbol that the attribute is attached to. For example, with <c>[CLSCompliant] class C { }</c> this would be the <see cref="INamedTypeSymbol"/> for <c>"C"</c>.
        /// </summary>
        public global::Microsoft.CodeAnalysis.ISymbol TargetSymbol { get; }
        /// <summary>
        /// Semantic model for the file that <see cref="TargetNode"/> is contained within.
        /// </summary>
        public global::Microsoft.CodeAnalysis.SemanticModel SemanticModel { get; }
        /// <summary>
        /// <see cref="AttributeData"/>s for any matching attributes on <see cref="TargetSymbol"/>. Always non-empty. All
        /// these attributes will have an <see cref="AttributeData.AttributeClass"/> whose fully qualified name metadata
        /// name matches the name requested in <see cref="SyntaxValueProviderExtensions.ForAttributeWithMetadataName"/>.
        /// <para>
        /// To get the entire list of attributes, use <see cref="ISymbol.GetAttributes"/> on <see cref="TargetSymbol"/>.
        /// </para>
        /// </summary>
        public global::System.Collections.Immutable.ImmutableArray<global::Microsoft.CodeAnalysis.AttributeData> Attributes { get; }
    }
}
#endif

#if !ROSLYN_4_3_1_OR_GREATER
using Microsoft.CodeAnalysis.Internal;
#endif
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// This file is ported and adapted from ComputeSharp (Sergio0694/ComputeSharp),
// more info in ThirdPartyNotices.txt in the root of the project.
using System;
using System.Buffers;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;

namespace Microsoft.CodeAnalysis
{
    internal ref struct ImmutableArrayBuilder<T>
    {
        /// <summary>
        /// The rented <see cref="Writer"/> instance to use.
        /// </summary>
        private global::Microsoft.CodeAnalysis.ImmutableArrayBuilder<T>.Writer writer;
        /// <summary>
        /// Creates a <see cref="ImmutableArrayBuilder{T}"/> value with a pooled underlying data writer.
        /// </summary>
        /// <returns>A <see cref="ImmutableArrayBuilder{T}"/> instance to write data to.</returns>
        public static global::Microsoft.CodeAnalysis.ImmutableArrayBuilder<T> Rent()
        {
            return new(new global::Microsoft.CodeAnalysis.ImmutableArrayBuilder<T>.Writer());
        }

        /// <summary>
        /// Creates a new <see cref="ImmutableArrayBuilder{T}"/> object with the specified parameters.
        /// </summary>
        /// <param name="writer">The target data writer to use.</param>
        private ImmutableArrayBuilder(global::Microsoft.CodeAnalysis.ImmutableArrayBuilder<T>.Writer writer)
        {
            this.writer = writer;
        }

        /// <inheritdoc cref="ImmutableArray{T}.Builder.Count"/>
        public readonly int Count {[MethodImpl(MethodImplOptions.AggressiveInlining)]
            get => this.writer!.Count; }

        /// <summary>
        /// Gets the data written to the underlying buffer so far, as a <see cref="ReadOnlySpan{T}"/>.
        /// </summary>
        [UnscopedRef]
        public readonly global::System.ReadOnlySpan<T> WrittenSpan {[MethodImpl(MethodImplOptions.AggressiveInlining)]
            get => this.writer!.WrittenSpan; }

        /// <inheritdoc cref="ImmutableArray{T}.Builder.Add(T)"/>
        public readonly void Add(T item)
        {
            this.writer!.Add(item);
        }

        /// <summary>
        /// Adds the specified items to the end of the array.
        /// </summary>
        /// <param name="items">The items to add at the end of the array.</param>
        public readonly void AddRange(scoped global::System.ReadOnlySpan<T> items)
        {
            this.writer!.AddRange(items);
        }

        /// <inheritdoc cref="ImmutableArray{T}.Builder.ToImmutable"/>
        public readonly global::System.Collections.Immutable.ImmutableArray<T> ToImmutable()
        {
            T[] array = this.writer!.WrittenSpan.ToArray();
            return global::System.Runtime.CompilerServices.Unsafe.As<T[], global::System.Collections.Immutable.ImmutableArray<T>>(ref array);
        }

        /// <inheritdoc cref="ImmutableArray{T}.Builder.ToArray"/>
        public readonly T[] ToArray()
        {
            return this.writer!.WrittenSpan.ToArray();
        }

        /// <summary>
        /// Gets an <see cref="IEnumerable{T}"/> instance for the current builder.
        /// </summary>
        /// <returns>An <see cref="IEnumerable{T}"/> instance for the current builder.</returns>
        /// <remarks>
        /// The builder should not be mutated while an enumerator is in use.
        /// </remarks>
        public readonly global::System.Collections.Generic.IEnumerable<T> AsEnumerable()
        {
            return this.writer!;
        }

        /// <inheritdoc/>
        public readonly override string ToString()
        {
            return this.writer!.WrittenSpan.ToString();
        }

        /// <inheritdoc cref="IDisposable.Dispose"/>
        public void Dispose()
        {
            global::Microsoft.CodeAnalysis.ImmutableArrayBuilder<T>.Writer writer = this.writer;
            this.writer = null;
            writer?.Dispose();
        }

        /// <summary>
        /// A class handling the actual buffer writing.
        /// </summary>
        private sealed class Writer : global::System.Collections.Generic.ICollection<T>, global::System.IDisposable
        {
            /// <summary>
            /// The underlying <typeparamref name="T"/> array.
            /// </summary>
            private T[] array;
            /// <summary>
            /// The starting offset within <see cref="array"/>.
            /// </summary>
            private int index;
            /// <summary>
            /// Creates a new <see cref="Writer"/> instance with the specified parameters.
            /// </summary>
            public Writer()
            {
                this.array = global::System.Buffers.ArrayPool<T>.Shared.Rent(typeof(T) == typeof(char) ? 1024 : 8);
                this.index = 0;
            }

            /// <inheritdoc cref="ImmutableArrayBuilder{T}.Count"/>
            public int Count {[MethodImpl(MethodImplOptions.AggressiveInlining)]
                get => this.index; }
            /// <inheritdoc cref="ImmutableArrayBuilder{T}.WrittenSpan"/>
            public global::System.ReadOnlySpan<T> WrittenSpan {[MethodImpl(MethodImplOptions.AggressiveInlining)]
                get => new(this.array!, 0, this.index); }

            bool ICollection<T>.IsReadOnly => true;

            /// <inheritdoc cref="ImmutableArrayBuilder{T}.Add"/>
            public void Add(T value)
            {
                EnsureCapacity(1);
                this.array![this.index++] = value;
            }

            /// <inheritdoc cref="ImmutableArrayBuilder{T}.AddRange"/>
            public void AddRange(global::System.ReadOnlySpan<T> items)
            {
                EnsureCapacity(items.Length);
                items.CopyTo(this.array.AsSpan(this.index)!);
                this.index += items.Length;
            }

            /// <inheritdoc/>
            public void Dispose()
            {
                T[] array = this.array;
                this.array = null;
                if (array is not null)
                {
                    global::System.Buffers.ArrayPool<T>.Shared.Return(array, clearArray: typeof(T) != typeof(char));
                }
            }

            void ICollection<T>.Clear()
            {
                throw new global::System.NotSupportedException();
            }

            bool ICollection<T>.Contains(T item)
            {
                throw new global::System.NotSupportedException();
            }

            void ICollection<T>.CopyTo(T[] array, int arrayIndex)
            {
                global::System.Array.Copy(this.array!, 0, array, arrayIndex, this.index);
            }

            global::System.Collections.Generic.IEnumerator<T> IEnumerable<T>.GetEnumerator()
            {
                T[] array = this.array!;
                int length = this.index;
                for (int i = 0; i < length; i++)
                {
                    yield return array[i]!;
                }
            }

            global::System.Collections.IEnumerator IEnumerable.GetEnumerator()
            {
                return ((global::System.Collections.Generic.IEnumerable<T>)this).GetEnumerator();
            }

            bool ICollection<T>.Remove(T item)
            {
                throw new global::System.NotSupportedException();
            }

            /// <summary>
            /// Ensures that <see cref="array"/> has enough free space to contain a given number of new items.
            /// </summary>
            /// <param name="requestedSize">The minimum number of items to ensure space for in <see cref="array"/>.</param>
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            private void EnsureCapacity(int requestedSize)
            {
                if (requestedSize > this.array!.Length - this.index)
                {
                    ResizeBuffer(requestedSize);
                }
            }

            /// <summary>
            /// Resizes <see cref="array"/> to ensure it can fit the specified number of new items.
            /// </summary>
            /// <param name="sizeHint">The minimum number of items to ensure space for in <see cref="array"/>.</param>
            [MethodImpl(MethodImplOptions.NoInlining)]
            private void ResizeBuffer(int sizeHint)
            {
                int minimumSize = this.index + sizeHint;
                T[] oldArray = this.array!;
                T[] newArray = global::System.Buffers.ArrayPool<T>.Shared.Rent(minimumSize);
                global::System.Array.Copy(oldArray, newArray, this.index);
                this.array = newArray;
                global::System.Buffers.ArrayPool<T>.Shared.Return(oldArray, clearArray: typeof(T) != typeof(char));
            }
        }
    }
}
#if !ROSLYN_4_3_1_OR_GREATER
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Threading;
using System;
using System.Collections.Immutable;

namespace Microsoft.CodeAnalysis
{
    internal static class SyntaxValueProviderExtensions
    {
        /// <summary>
        /// Creates an <see cref="IncrementalValuesProvider{T}"/> that can provide a transform over all <see
        /// cref="SyntaxNode"/>s if that node has an attribute on it that binds to a <see cref="INamedTypeSymbol"/> with the
        /// same fully-qualified metadata as the provided <paramref name="fullyQualifiedMetadataName"/>. <paramref
        /// name="fullyQualifiedMetadataName"/> should be the fully-qualified, metadata name of the attribute, including the
        /// <c>Attribute</c> suffix.  For example <c>"System.CLSCompliantAttribute</c> for <see cref="CLSCompliantAttribute"/>.
        /// </summary>
        /// <param name="syntaxValueProvider">The source <see cref="SyntaxValueProvider"/> instance to use.</param>
        /// <param name="fullyQualifiedMetadataName">The fully qualified metadata name of the attribute to look for.</param>
        /// <param name="predicate">A function that determines if the given <see cref="SyntaxNode"/> attribute target (<see
        /// cref="GeneratorAttributeSyntaxContext.TargetNode"/>) should be transformed.  Nodes that do not pass this
        /// predicate will not have their attributes looked at at all.</param>
        /// <param name="transform">A function that performs the transform. This will only be passed nodes that return <see
        /// langword="true"/> for <paramref name="predicate"/> and which have a matching <see cref="AttributeData"/> whose
        /// <see cref="AttributeData.AttributeClass"/> has the same fully qualified, metadata name as <paramref
        /// name="fullyQualifiedMetadataName"/>.</param>
        public static global::Microsoft.CodeAnalysis.IncrementalValuesProvider<T> ForAttributeWithMetadataName<T>(this global::Microsoft.CodeAnalysis.SyntaxValueProvider syntaxValueProvider, string fullyQualifiedMetadataName, global::System.Func<global::Microsoft.CodeAnalysis.SyntaxNode, global::System.Threading.CancellationToken, bool> predicate, global::System.Func<global::Microsoft.CodeAnalysis.Internal.GeneratorAttributeSyntaxContext, global::System.Threading.CancellationToken, T> transform)
        {
            return syntaxValueProvider.CreateSyntaxProvider(predicate, (context, token) =>
            {
                ISymbol? symbol = context.SemanticModel.GetDeclaredSymbol(context.Node, token);
                // If the syntax node doesn't have a declared symbol, just skip this node. This would be
                // the case for eg. lambda attributes, but those are not supported by the MVVM Toolkit.
                if (symbol is null)
                {
                    return null;
                }

                // Skip symbols without the target attribute
                if (!symbol.TryGetAttributeWithFullyQualifiedMetadataName(fullyQualifiedMetadataName, out AttributeData? attributeData))
                {
                    return null;
                }

                // Edge case: if the symbol is a partial method, skip the implementation part and only process the partial method
                // definition. This is needed because attributes will be reported as available on both the definition and the
                // implementation part. To avoid generating duplicate files, we only give priority to the definition part.
                // On Roslyn 4.3+, ForAttributeWithMetadataName will already only return the symbol the attribute was located on.
                if (symbol is IMethodSymbol { IsPartialDefinition: false, PartialDefinitionPart: not null })
                {
                    return null;
                }

                // Create the GeneratorAttributeSyntaxContext value to pass to the input transform. The attributes array
                // will only ever have a single value, but that's fine with the attributes the various generators look for.
                global::Microsoft.CodeAnalysis.Internal.GeneratorAttributeSyntaxContext syntaxContext = new(targetNode: context.Node, targetSymbol: symbol, semanticModel: context.SemanticModel, attributes: ImmutableArray.Create(attributeData));
                return new Option<T>(transform(syntaxContext, token));
            }).Where(static item => item is not null).Select(static (item, _) => item!.Value)!;
        }

        /// <summary>
        /// A simple record to wrap a value that might be missing.
        /// </summary>
        /// <typeparam name="T">The type of values to wrap</typeparam>
        /// <param name="Value">The wrapped value, if it exists.</param>
        private sealed record Option<T>(T? Value);
    }
}
#endif

using System;
using Feast.CodeAnalysis;

namespace Microsoft.CodeAnalysis
{
    internal static class ISymbolExtensions
    {
        public static bool Is(this global::Microsoft.CodeAnalysis.ISymbol symbol, global::Microsoft.CodeAnalysis.ISymbol other) => global::Microsoft.CodeAnalysis.SymbolEqualityComparer.Default.Equals(symbol, other);
        public static string GlobalName(this global::Microsoft.CodeAnalysis.ISymbol symbol) => symbol.ToDisplayString(global::Microsoft.CodeAnalysis.SymbolDisplayFormat.FullyQualifiedFormat);
        public static string GetFullyQualifiedName(this global::Microsoft.CodeAnalysis.ISymbol symbol) => symbol.ToDisplayString(global::Microsoft.CodeAnalysis.SymbolDisplayFormat.FullyQualifiedFormat);
        public static bool IsInitOnly(this global::Microsoft.CodeAnalysis.IPropertySymbol symbol) => !symbol.IsReadOnly && symbol.SetMethod!.IsInitOnly;
        public static global::System.Collections.Generic.IEnumerable<global::Microsoft.CodeAnalysis.CSharp.SyntaxKind> GetSyntaxKind(this global::Microsoft.CodeAnalysis.Accessibility accessibility)
        {
            switch (accessibility)
            {
                case global::Microsoft.CodeAnalysis.Accessibility.Public:
                    yield return global::Microsoft.CodeAnalysis.CSharp.SyntaxKind.PublicKeyword;
                    yield break;
                case global::Microsoft.CodeAnalysis.Accessibility.Protected:
                    yield return global::Microsoft.CodeAnalysis.CSharp.SyntaxKind.ProtectedKeyword;
                    yield break;
                case global::Microsoft.CodeAnalysis.Accessibility.Internal:
                    yield return global::Microsoft.CodeAnalysis.CSharp.SyntaxKind.InternalKeyword;
                    yield break;
                case global::Microsoft.CodeAnalysis.Accessibility.Private:
                    yield return global::Microsoft.CodeAnalysis.CSharp.SyntaxKind.PrivateKeyword;
                    yield break;
                case global::Microsoft.CodeAnalysis.Accessibility.ProtectedOrInternal:
                    yield return global::Microsoft.CodeAnalysis.CSharp.SyntaxKind.ProtectedKeyword;
                    yield return global::Microsoft.CodeAnalysis.CSharp.SyntaxKind.InternalKeyword;
                    yield break;
                default:
                    throw new global::System.ArgumentOutOfRangeException(nameof(accessibility), accessibility, null);
            }
        }

#if !ROSLYN_4_3_1_OR_GREATER
        /// <summary>
        /// Tries to get an attribute with the specified fully qualified metadata name.
        /// </summary>
        /// <param name="symbol">The input <see cref="ISymbol"/> instance to check.</param>
        /// <param name="name">The attribute name to look for.</param>
        /// <param name="attributeData">The resulting attribute, if it was found.</param>
        /// <returns>Whether or not <paramref name="symbol"/> has an attribute with the specified name.</returns>
        public static bool TryGetAttributeWithFullyQualifiedMetadataName(this global::Microsoft.CodeAnalysis.ISymbol symbol, string name, [global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Microsoft.CodeAnalysis.AttributeData attributeData)
        {
            foreach (var attribute in symbol.GetAttributes())
            {
                if (attribute.AttributeClass?.HasFullyQualifiedMetadataName(name) == true)
                {
                    attributeData = attribute;
                    return true;
                }
            }

            attributeData = null;
            return false;
        }
#endif
    }
}
using System;
using System.Linq;

namespace Microsoft.CodeAnalysis
{
    internal static class ITypeSymbolExtensions
    {
        /// <summary>
        /// Checks whether or not a given type symbol has a specified fully qualified metadata name.
        /// </summary>
        /// <param name="symbol">The input <see cref="ITypeSymbol"/> instance to check.</param>
        /// <param name="name">The full name to check.</param>
        /// <returns>Whether <paramref name="symbol"/> has a full name equals to <paramref name="name"/>.</returns>
        public static bool HasFullyQualifiedMetadataName(this global::Microsoft.CodeAnalysis.ITypeSymbol symbol, string name)
        {
            using global::Microsoft.CodeAnalysis.ImmutableArrayBuilder<char> builder = global::Microsoft.CodeAnalysis.ImmutableArrayBuilder<char>.Rent();
            symbol.AppendFullyQualifiedMetadataName(in builder);
            return builder.WrittenSpan.SequenceEqual(name.AsSpan());
        }

        /// <summary>
        /// Appends the fully qualified metadata name for a given symbol to a target builder.
        /// </summary>
        /// <param name="symbol">The input <see cref="ITypeSymbol"/> instance.</param>
        /// <param name="builder">The target <see cref="ImmutableArrayBuilder{T}"/> instance.</param>
        private static void AppendFullyQualifiedMetadataName(this global::Microsoft.CodeAnalysis.ITypeSymbol symbol, in global::Microsoft.CodeAnalysis.ImmutableArrayBuilder<char> builder)
        {
            static void BuildFrom(global::Microsoft.CodeAnalysis.ISymbol? symbol, in global::Microsoft.CodeAnalysis.ImmutableArrayBuilder<global::System.Char> builder)
            {
                switch (symbol)
                {
                    // Namespaces that are nested also append a leading '.'
                    case global::Microsoft.CodeAnalysis.INamespaceSymbol { ContainingNamespace.IsGlobalNamespace: false }:
                        BuildFrom(symbol.ContainingNamespace, in builder);
                        builder.Add('.');
                        builder.AddRange(symbol.MetadataName.AsSpan());
                        break;
                    // Other namespaces (ie. the one right before global) skip the leading '.'
                    case global::Microsoft.CodeAnalysis.INamespaceSymbol { IsGlobalNamespace: false }:
                        builder.AddRange(symbol.MetadataName.AsSpan());
                        break;
                    // Types with no namespace just have their metadata name directly written
                    case global::Microsoft.CodeAnalysis.ITypeSymbol { ContainingSymbol: global::Microsoft.CodeAnalysis.INamespaceSymbol { IsGlobalNamespace: true } }:
                        builder.AddRange(symbol.MetadataName.AsSpan());
                        break;
                    // Types with a containing non-global namespace also append a leading '.'
                    case global::Microsoft.CodeAnalysis.ITypeSymbol { ContainingSymbol: global::Microsoft.CodeAnalysis.INamespaceSymbol namespaceSymbol }:
                        BuildFrom(namespaceSymbol, in builder);
                        builder.Add('.');
                        builder.AddRange(symbol.MetadataName.AsSpan());
                        break;
                    // Nested types append a leading '+'
                    case global::Microsoft.CodeAnalysis.ITypeSymbol { ContainingSymbol: global::Microsoft.CodeAnalysis.ITypeSymbol typeSymbol }:
                        BuildFrom(typeSymbol, in builder);
                        builder.Add('+');
                        builder.AddRange(symbol.MetadataName.AsSpan());
                        break;
                    default:
                        break;
                }
            }

            BuildFrom(symbol, in builder);
        }

        public static T AsNoneErrorType<T>(this T symbol)
            where T : global::Microsoft.CodeAnalysis.ITypeSymbol
        {
            return symbol is global::Microsoft.CodeAnalysis.IErrorTypeSymbol errorTypeSymbol ? (T)errorTypeSymbol.CandidateSymbols.FirstOrDefault()! : (T)symbol;
        }

        public static global::Microsoft.CodeAnalysis.INamespaceOrTypeSymbol AsNoneErrorType(this global::Microsoft.CodeAnalysis.INamespaceOrTypeSymbol symbol)
        {
            return symbol is global::Microsoft.CodeAnalysis.IErrorTypeSymbol errorTypeSymbol ? (global::Microsoft.CodeAnalysis.INamespaceOrTypeSymbol)errorTypeSymbol.CandidateSymbols.FirstOrDefault()! : symbol;
        }

        public static bool IsJsonBool(this global::Microsoft.CodeAnalysis.ITypeSymbol symbol) => symbol.SpecialType == global::Microsoft.CodeAnalysis.SpecialType.System_Boolean;
        public static bool IsJsonNumber(this global::Microsoft.CodeAnalysis.ITypeSymbol symbol) => symbol is { SpecialType: >= global::Microsoft.CodeAnalysis.SpecialType.System_SByte and <= global::Microsoft.CodeAnalysis.SpecialType.System_Single };
        public static bool IsJsonString(this global::Microsoft.CodeAnalysis.ITypeSymbol symbol) => symbol.SpecialType is global::Microsoft.CodeAnalysis.SpecialType.System_String or global::Microsoft.CodeAnalysis.SpecialType.System_Char;
    }
}
#nullable enable
using System;
namespace System
{
    [global::System.AttributeUsage(global::System.AttributeTargets.Class | global::System.AttributeTargets.Struct | global::System.AttributeTargets.Interface | global::System.AttributeTargets.Enum | global::System.AttributeTargets.Delegate)]
    public class LiteralAttribute : Attribute
    {
        public string? FieldName { get; set; }
    
        public LiteralAttribute(string belongToFullyQualifiedClassName){ }
    }
}
// <auto-generated/> By Feast.CodeAnalysis
#pragma warning disable
#nullable enable
namespace Namespace_Andrei
{
    partial class Class_Ignat
    {
        internal static string Text = """
namespace DemoLit
{
    internal class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
}
""".Replace("\"^\"\"", "\"\"\"");
    }
}
using System;
using System.Linq;
using Feast.CodeAnalysis;

namespace Microsoft.CodeAnalysis
{
    internal static class SyntaxExtensions
    {
        public static global::System.Collections.Generic.IEnumerable<global::Microsoft.CodeAnalysis.CSharp.Syntax.AttributeSyntax> GetAllAttributes(this global::Microsoft.CodeAnalysis.SyntaxNode syntax)
        {
            var attributeLists = syntax switch
            {
                global::Microsoft.CodeAnalysis.CSharp.Syntax.CompilationUnitSyntax compilationUnitSyntax => compilationUnitSyntax.AttributeLists,
                global::Microsoft.CodeAnalysis.CSharp.Syntax.MemberDeclarationSyntax memberDeclarationSyntax => memberDeclarationSyntax.AttributeLists,
                global::Microsoft.CodeAnalysis.CSharp.Syntax.LambdaExpressionSyntax lambdaExpressionSyntax => lambdaExpressionSyntax.AttributeLists,
                global::Microsoft.CodeAnalysis.CSharp.Syntax.BaseParameterSyntax baseParameterSyntax => baseParameterSyntax.AttributeLists,
                global::Microsoft.CodeAnalysis.CSharp.Syntax.StatementSyntax statementSyntax => statementSyntax.AttributeLists,
                _ => throw new global::System.NotSupportedException($"{syntax.GetType()} has no attribute")};
            return attributeLists.SelectMany(attributeListSyntax => attributeListSyntax.Attributes);
        }

        public static global::System.Collections.Generic.IEnumerable<global::Microsoft.CodeAnalysis.CSharp.Syntax.AttributeSyntax> GetSpecifiedAttributes(this global::Microsoft.CodeAnalysis.SyntaxNode syntax, global::Microsoft.CodeAnalysis.SemanticModel semanticModel, string fullAttributeName, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
        {
            foreach (var attributeSyntax in syntax.GetAllAttributes())
            {
                if (cancellationToken.IsCancellationRequested)
                    yield break;
                if (semanticModel.GetSymbolInfo(attributeSyntax, cancellationToken).Symbol is not global::Microsoft.CodeAnalysis.IMethodSymbol attributeSymbol)
                    continue;
                string attributeName = attributeSymbol.ContainingType.ToDisplayString();
                if (attributeName == fullAttributeName)
                    yield return attributeSyntax;
            }
        }

        public static global::Microsoft.CodeAnalysis.CSharp.Syntax.AttributeSyntax GetSpecifiedAttribute(this global::Microsoft.CodeAnalysis.SyntaxNode syntax, global::Microsoft.CodeAnalysis.SemanticModel semanticModel, string fullAttributeName, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
        {
            foreach (var attributeSyntax in syntax.GetSpecifiedAttributes(semanticModel, fullAttributeName, cancellationToken))
            {
                return attributeSyntax;
            }

            return null;
        }

        public static bool HasSpecifiedAttribute(this global::Microsoft.CodeAnalysis.CSharp.Syntax.MemberDeclarationSyntax syntax, global::Microsoft.CodeAnalysis.SemanticModel semanticModel, string fullAttributeName)
        {
            return syntax.GetSpecifiedAttribute(semanticModel, fullAttributeName)is not null;
        }

        public static string GetArgumentString(this global::Microsoft.CodeAnalysis.CSharp.Syntax.AttributeArgumentSyntax syntax)
        {
            if (syntax.Expression is not global::Microsoft.CodeAnalysis.CSharp.Syntax.LiteralExpressionSyntax literalExpressionSyntax)
                return null;
            if (!literalExpressionSyntax.IsKind(global::Microsoft.CodeAnalysis.CSharp.SyntaxKind.StringLiteralExpression))
                return null;
            return literalExpressionSyntax.Token.ValueText;
        }

        public static global::Microsoft.CodeAnalysis.CSharp.Syntax.TypeSyntax GetArgumentType(this global::Microsoft.CodeAnalysis.CSharp.Syntax.AttributeArgumentSyntax syntax)
        {
            if (syntax.Expression is not global::Microsoft.CodeAnalysis.CSharp.Syntax.TypeOfExpressionSyntax typeOfExpression)
                return null;
            return typeOfExpression.Type;
        }

        public static global::Microsoft.CodeAnalysis.CSharp.Syntax.NameSyntax ToNameSyntax(this string text, int offset = 0, bool consumeFullText = true)
        {
            return global::Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParseName(text, offset, consumeFullText);
        }

        public static global::Microsoft.CodeAnalysis.CSharp.Syntax.NamespaceDeclarationSyntax ToNamespaceDeclaration(this global::Microsoft.CodeAnalysis.CSharp.Syntax.NameSyntax syntax)
        {
            return global::Microsoft.CodeAnalysis.CSharp.SyntaxFactory.NamespaceDeclaration(syntax);
        }

        public static global::Microsoft.CodeAnalysis.CSharp.Syntax.ClassDeclarationSyntax ToClassDeclaration(this string identifier)
        {
            return global::Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ClassDeclaration(identifier);
        }

        public static global::Microsoft.CodeAnalysis.CSharp.Syntax.CompilationUnitSyntax AddMembers(this global::Microsoft.CodeAnalysis.CSharp.Syntax.CompilationUnitSyntax syntax, params string[] members)
        {
            return syntax.AddMembers(members.Select(x => global::Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParseMemberDeclaration(x) ?? throw new global::System.Exception($"Text : {x} , Parse failed")).ToArray());
        }

        public static global::Microsoft.CodeAnalysis.CSharp.Syntax.ClassDeclarationSyntax AddMembers(this global::Microsoft.CodeAnalysis.CSharp.Syntax.ClassDeclarationSyntax syntax, params string[] members)
        {
            return syntax.AddMembers(members.Select(x => global::Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParseMemberDeclaration(x) ?? throw new global::System.Exception($"Text : {x} , Parse failed")).ToArray());
        }

        public static global::Microsoft.CodeAnalysis.CSharp.Syntax.CompilationUnitSyntax AddUsings(this global::Microsoft.CodeAnalysis.CSharp.Syntax.CompilationUnitSyntax syntax, params string[] usings)
        {
            return syntax.AddUsings(usings.Select(x => global::Microsoft.CodeAnalysis.CSharp.SyntaxFactory.UsingDirective(global::Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParseName(x))).ToArray());
        }

        public static global::Microsoft.CodeAnalysis.CSharp.Syntax.CompilationUnitSyntax AddNamespace(this global::Microsoft.CodeAnalysis.CSharp.Syntax.CompilationUnitSyntax syntax, string @namespace)
        {
            return syntax.AddMembers(global::Microsoft.CodeAnalysis.CSharp.SyntaxFactory.NamespaceDeclaration(global::Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParseName(@namespace)));
        }

        public static global::Microsoft.CodeAnalysis.CSharp.Syntax.ClassDeclarationSyntax AddModifiers(this global::Microsoft.CodeAnalysis.CSharp.Syntax.ClassDeclarationSyntax syntax, params global::Microsoft.CodeAnalysis.CSharp.SyntaxKind[] items)
        {
            return syntax.AddModifiers(items.Select(x => global::Microsoft.CodeAnalysis.CSharp.SyntaxFactory.Token(x)).ToArray());
        }

        public static global::Microsoft.CodeAnalysis.CSharp.Syntax.ClassDeclarationSyntax AddBaseListTypes(this global::Microsoft.CodeAnalysis.CSharp.Syntax.ClassDeclarationSyntax syntax, params string[] identifiers)
        {
            return syntax.AddBaseListTypes(identifiers.Select(x => global::Microsoft.CodeAnalysis.CSharp.SyntaxFactory.SimpleBaseType(global::Microsoft.CodeAnalysis.CSharp.SyntaxFactory.IdentifierName(x))).ToArray());
        }
    }
}
using System;
using System.Linq;

namespace Microsoft.CodeAnalysis
{
    internal static class TypedConstantExtensions
    {
        private static global::System.Type GetElementType(this global::System.Type type)
        {
            return type.IsArray ? type.GetElementType()! : throw new global::System.ArgumentException("type is not an array");
        }

        internal static object GenericList(this global::System.Type type, params object[] values)
        {
            var listType = type.MakeGenericType(type.GetGenericArguments());
            var list = global::System.Activator.CreateInstance(listType);
            var add = listType.GetMethod(nameof(global::System.Collections.Generic.List<object>.Add))!;
            foreach (var value in values)
            {
                add.Invoke(list, new object[] { value });
            }

            return list;
        }

        private static object ToArray(object genericList)
        {
            var toArray = genericList.GetType().GetMethod(nameof(global::System.Collections.Generic.List<object>.ToArray))!;
            return toArray.Invoke(genericList, null);
        }

        public static object GetArgumentValue(this global::Microsoft.CodeAnalysis.TypedConstant constant) => constant.Kind switch
        {
            global::Microsoft.CodeAnalysis.TypedConstantKind.Array => constant.Values.Select(x => x.GetArgumentValue()).ToArray(),
            global::Microsoft.CodeAnalysis.TypedConstantKind.Error => null,
            global::Microsoft.CodeAnalysis.TypedConstantKind.Type => (constant.Value as global::Microsoft.CodeAnalysis.INamedTypeSymbol)?.ToType(),
            _ => constant.Value
        };
        public static object GetArgumentValue(this global::Microsoft.CodeAnalysis.TypedConstant constant, global::System.Type type)
        {
            var value = constant.GetArgumentValue();
            if (!type.IsArray)
                return type.IsEnum ? value == null ? null : global::System.Enum.ToObject(type, (int)value) : value;
            if (value is not object[] arr)
                throw new global::System.ArgumentException("constant is not an array");
            var ret = global::System.Array.CreateInstance(type.GetElementType()!, arr.Length);
            global::System.Array.Copy(arr, ret, arr.Length);
            return ret;
        }

        public static global::Microsoft.CodeAnalysis.INamedTypeSymbol GetArgumentType(this global::Microsoft.CodeAnalysis.TypedConstant constant) => constant.Kind == global::Microsoft.CodeAnalysis.TypedConstantKind.Type ? constant.Value as global::Microsoft.CodeAnalysis.INamedTypeSymbol : throw new global::System.ArgumentException("constant is not a type");
        public static string GetArgumentString(this global::Microsoft.CodeAnalysis.TypedConstant constant) => constant.Kind == global::Microsoft.CodeAnalysis.TypedConstantKind.Primitive ? constant.Value as string : throw new global::System.ArgumentException("constant is not a string");
        public static T GetArgumentEnum<T>(this global::Microsoft.CodeAnalysis.TypedConstant constant)
            where T : global::System.Enum => constant.Kind == global::Microsoft.CodeAnalysis.TypedConstantKind.Enum ? (T)constant.Value : throw new global::System.ArgumentException("constant is not an enum");
        public static T? GetArgumentPrimitive<T>(this global::Microsoft.CodeAnalysis.TypedConstant constant)
            where T : struct => constant.Kind == global::Microsoft.CodeAnalysis.TypedConstantKind.Primitive ? (T? )constant.Value : throw new global::System.ArgumentException("constant is not a primitive");
        public static T[] GetArgumentArray<T>(this global::Microsoft.CodeAnalysis.TypedConstant constant) => constant.Kind == global::Microsoft.CodeAnalysis.TypedConstantKind.Array ? constant.Values.Select(x => (T)x.Value).ToArray() : throw new global::System.ArgumentException("constant is not an array");
    }
}
// <auto-generated/>
#pragma warning disable

[assembly: global::System.Runtime.CompilerServices.TypeForwardedTo(typeof(global::System.Runtime.CompilerServices.IsExternalInit))]
// <auto-generated/>
#pragma warning disable

[assembly: global::System.Runtime.CompilerServices.TypeForwardedTo(typeof(global::System.Runtime.CompilerServices.RequiresLocationAttribute))]

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/CodeAnalysis

RSCG – RSCG_JSON2Class

RSCG – RSCG_JSON2Class
 
 

name RSCG_JSON2Class
nuget https://www.nuget.org/packages/RSCG_JSON2Class/
link https://github.com/ignatandrei/RSCG_JSON2Class
author Andrei Ignat

transform any json into a class

 

This is how you can use RSCG_JSON2Class .

The code that you start with is


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
<ItemGroup>
  <None Remove="testData.json" />
</ItemGroup>
<ItemGroup>
  <AdditionalFiles Include="testData.json">
    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
  </AdditionalFiles>
</ItemGroup>
	

	<ItemGroup>
  <PackageReference Include="RSCG_JSON2Class" Version="2024.2.29.807" OutputItemType="Analyzer" ReferenceOutputAssembly="false"  />
</ItemGroup>
	<PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
		<GenerateDocumentationFile>True</GenerateDocumentationFile>
	</PropertyGroup>


</Project>


The code that you will use is


using System.Text.Json;
var testData = JsonSerializer.Deserialize<JSON2ClassConsole.SettingsJson.testData>(System.IO.File.ReadAllText("testData.json"));
ArgumentNullException.ThrowIfNull(testData);
Console.WriteLine(testData.Logging.LogLevel.Default);
Console.WriteLine(testData.DictData.Number_2);


{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "MicrosoftHostingLifetime": "Trace"
    }
  },
  "PropChars": {
    "a": "ab'"
  },
  "NoProp": {},
  "AllowedHosts": "*",
  "MyTest": "'aa < >",
  "DictData": {
    "Test": {
      "1234a": [
        "1a",
        "b"
      ]
    },
    "A": "asdasd",
    "2": "asdasd",
    "MyNumber": 10,
    "55": {
      "a": "b1",
      "2": "test1"
    }
  }
}

 

The code that is generated is

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using appSettingsEditor;
namespace JSON2ClassConsole.SettingsJson
{

    //[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("RSCG_JSON2Class", "2024.2.24.1940")]
    public partial class LogLevel 
    {
        public object GetFromPropertyName(string propName, bool returnNull =false){
            
            propName=propName?.ToUpper();
            
            switch(propName){
                
                case "DEFAULT":
                    return this.Default ;
                
                case "MICROSOFT":
                    return this.Microsoft ;
                
                case "MICROSOFTHOSTINGLIFETIME":
                    return this.MicrosoftHostingLifetime ;
                
                default:
                    if(returnNull)
                        return null;

                    throw new ArgumentException("cannot found from LogLevel prop "+propName);            

            }
            
            
        }

        public IEnumerable<string> Properties(){
            
                yield return "Default" ;
            
                yield return "Microsoft" ;
            
                yield return "MicrosoftHostingLifetime" ;
            
            yield break;
        }
        
        [System.Text.Json.Serialization.JsonPropertyName("Default")]
        public string Default { get; set; }
        
        [System.Text.Json.Serialization.JsonPropertyName("Microsoft")]
        public string Microsoft { get; set; }
        
        [System.Text.Json.Serialization.JsonPropertyName("MicrosoftHostingLifetime")]
        public string MicrosoftHostingLifetime { get; set; }
        
        
    }

    //[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("RSCG_JSON2Class", "2024.2.24.1940")]
    public partial class Logging 
    {
        public object GetFromPropertyName(string propName, bool returnNull =false){
            
            propName=propName?.ToUpper();
            
            switch(propName){
                
                case "LOGLEVEL":
                    return this.LogLevel ;
                
                default:
                    if(returnNull)
                        return null;

                    throw new ArgumentException("cannot found from Logging prop "+propName);            

            }
            
            
        }

        public IEnumerable<string> Properties(){
            
                yield return "LogLevel" ;
            
            yield break;
        }
        
        [System.Text.Json.Serialization.JsonPropertyName("LogLevel")]
        public LogLevel LogLevel { get; set; }
        
        
    }

    //[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("RSCG_JSON2Class", "2024.2.24.1940")]
    public partial class PropChars 
    {
        public object GetFromPropertyName(string propName, bool returnNull =false){
            
            propName=propName?.ToUpper();
            
            switch(propName){
                
                case "A":
                    return this.A ;
                
                default:
                    if(returnNull)
                        return null;

                    throw new ArgumentException("cannot found from PropChars prop "+propName);            

            }
            
            
        }

        public IEnumerable<string> Properties(){
            
                yield return "A" ;
            
            yield break;
        }
        
        [System.Text.Json.Serialization.JsonPropertyName("a")]
        public string A { get; set; }
        
        
    }

    //[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("RSCG_JSON2Class", "2024.2.24.1940")]
    public partial class NoProp 
    {
        public object GetFromPropertyName(string propName, bool returnNull =false){
            
            propName=propName?.ToUpper();
            
            switch(propName){
                
                default:
                    if(returnNull)
                        return null;

                    throw new ArgumentException("cannot found from NoProp prop "+propName);            

            }
            
            
        }

        public IEnumerable<string> Properties(){
            
            yield break;
        }
        
        
    }

    //[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("RSCG_JSON2Class", "2024.2.24.1940")]
    public partial class Test 
    {
        public object GetFromPropertyName(string propName, bool returnNull =false){
            
            propName=propName?.ToUpper();
            
            switch(propName){
                
                case "NUMBER_1234A":
                    return this.Number_1234a ;
                
                default:
                    if(returnNull)
                        return null;

                    throw new ArgumentException("cannot found from Test prop "+propName);            

            }
            
            
        }

        public IEnumerable<string> Properties(){
            
                yield return "Number_1234a" ;
            
            yield break;
        }
        
        [System.Text.Json.Serialization.JsonPropertyName("1234a")]
        public IList<string> Number_1234a { get; set; }
        
        
    }

    //[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("RSCG_JSON2Class", "2024.2.24.1940")]
    public partial class Number_55 
    {
        public object GetFromPropertyName(string propName, bool returnNull =false){
            
            propName=propName?.ToUpper();
            
            switch(propName){
                
                case "A":
                    return this.A ;
                
                case "NUMBER_2":
                    return this.Number_2 ;
                
                default:
                    if(returnNull)
                        return null;

                    throw new ArgumentException("cannot found from Number_55 prop "+propName);            

            }
            
            
        }

        public IEnumerable<string> Properties(){
            
                yield return "A" ;
            
                yield return "Number_2" ;
            
            yield break;
        }
        
        [System.Text.Json.Serialization.JsonPropertyName("a")]
        public string A { get; set; }
        
        [System.Text.Json.Serialization.JsonPropertyName("2")]
        public string Number_2 { get; set; }
        
        
    }

    //[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("RSCG_JSON2Class", "2024.2.24.1940")]
    public partial class DictData 
    {
        public object GetFromPropertyName(string propName, bool returnNull =false){
            
            propName=propName?.ToUpper();
            
            switch(propName){
                
                case "TEST":
                    return this.Test ;
                
                case "A":
                    return this.A ;
                
                case "NUMBER_2":
                    return this.Number_2 ;
                
                case "MYNUMBER":
                    return this.MyNumber ;
                
                case "NUMBER_55":
                    return this.Number_55 ;
                
                default:
                    if(returnNull)
                        return null;

                    throw new ArgumentException("cannot found from DictData prop "+propName);            

            }
            
            
        }

        public IEnumerable<string> Properties(){
            
                yield return "Test" ;
            
                yield return "A" ;
            
                yield return "Number_2" ;
            
                yield return "MyNumber" ;
            
                yield return "Number_55" ;
            
            yield break;
        }
        
        [System.Text.Json.Serialization.JsonPropertyName("Test")]
        public Test Test { get; set; }
        
        [System.Text.Json.Serialization.JsonPropertyName("A")]
        public string A { get; set; }
        
        [System.Text.Json.Serialization.JsonPropertyName("2")]
        public string Number_2 { get; set; }
        
        [System.Text.Json.Serialization.JsonPropertyName("MyNumber")]
        public int MyNumber { get; set; }
        
        [System.Text.Json.Serialization.JsonPropertyName("55")]
        public Number_55 Number_55 { get; set; }
        
        
    }

    //[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("RSCG_JSON2Class", "2024.2.24.1940")]
    public partial class test 
    {
        public object GetFromPropertyName(string propName, bool returnNull =false){
            
            propName=propName?.ToUpper();
            
            switch(propName){
                
                case "LOGGING":
                    return this.Logging ;
                
                case "PROPCHARS":
                    return this.PropChars ;
                
                case "NOPROP":
                    return this.NoProp ;
                
                case "ALLOWEDHOSTS":
                    return this.AllowedHosts ;
                
                case "MYTEST":
                    return this.MyTest ;
                
                case "DICTDATA":
                    return this.DictData ;
                
                default:
                    if(returnNull)
                        return null;

                    throw new ArgumentException("cannot found from test prop "+propName);            

            }
            
            
        }

        public IEnumerable<string> Properties(){
            
                yield return "Logging" ;
            
                yield return "PropChars" ;
            
                yield return "NoProp" ;
            
                yield return "AllowedHosts" ;
            
                yield return "MyTest" ;
            
                yield return "DictData" ;
            
            yield break;
        }
        
        [System.Text.Json.Serialization.JsonPropertyName("Logging")]
        public Logging Logging { get; set; }
        
        [System.Text.Json.Serialization.JsonPropertyName("PropChars")]
        public PropChars PropChars { get; set; }
        
        [System.Text.Json.Serialization.JsonPropertyName("NoProp")]
        public NoProp NoProp { get; set; }
        
        [System.Text.Json.Serialization.JsonPropertyName("AllowedHosts")]
        public string AllowedHosts { get; set; }
        
        [System.Text.Json.Serialization.JsonPropertyName("MyTest")]
        public string MyTest { get; set; }
        
        [System.Text.Json.Serialization.JsonPropertyName("DictData")]
        public DictData DictData { get; set; }
        
        
    }

}

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace JSON2ClassConsole.SettingsJson
{

    //[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("RSCG_JSON2Class", "2024.2.29.807")]
    public partial class LogLevel 
    {
        public object GetFromPropertyName(string propName, bool returnNull =false){
            
            propName=propName?.ToUpper();
            
            switch(propName){
                
                case "DEFAULT":
                    return this.Default ;
                
                case "MICROSOFT":
                    return this.Microsoft ;
                
                case "MICROSOFTHOSTINGLIFETIME":
                    return this.MicrosoftHostingLifetime ;
                
                default:
                    if(returnNull)
                        return null;

                    throw new ArgumentException("cannot found from LogLevel prop "+propName);            

            }
            
            
        }

        public IEnumerable<string> Properties(){
            
                yield return "Default" ;
            
                yield return "Microsoft" ;
            
                yield return "MicrosoftHostingLifetime" ;
            
            yield break;
        }
        
        [System.Text.Json.Serialization.JsonPropertyName("Default")]
        public string Default { get; set; }
        
        [System.Text.Json.Serialization.JsonPropertyName("Microsoft")]
        public string Microsoft { get; set; }
        
        [System.Text.Json.Serialization.JsonPropertyName("MicrosoftHostingLifetime")]
        public string MicrosoftHostingLifetime { get; set; }
        
        
    }

    //[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("RSCG_JSON2Class", "2024.2.29.807")]
    public partial class Logging 
    {
        public object GetFromPropertyName(string propName, bool returnNull =false){
            
            propName=propName?.ToUpper();
            
            switch(propName){
                
                case "LOGLEVEL":
                    return this.LogLevel ;
                
                default:
                    if(returnNull)
                        return null;

                    throw new ArgumentException("cannot found from Logging prop "+propName);            

            }
            
            
        }

        public IEnumerable<string> Properties(){
            
                yield return "LogLevel" ;
            
            yield break;
        }
        
        [System.Text.Json.Serialization.JsonPropertyName("LogLevel")]
        public LogLevel LogLevel { get; set; }
        
        
    }

    //[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("RSCG_JSON2Class", "2024.2.29.807")]
    public partial class PropChars 
    {
        public object GetFromPropertyName(string propName, bool returnNull =false){
            
            propName=propName?.ToUpper();
            
            switch(propName){
                
                case "A":
                    return this.A ;
                
                default:
                    if(returnNull)
                        return null;

                    throw new ArgumentException("cannot found from PropChars prop "+propName);            

            }
            
            
        }

        public IEnumerable<string> Properties(){
            
                yield return "A" ;
            
            yield break;
        }
        
        [System.Text.Json.Serialization.JsonPropertyName("a")]
        public string A { get; set; }
        
        
    }

    //[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("RSCG_JSON2Class", "2024.2.29.807")]
    public partial class NoProp 
    {
        public object GetFromPropertyName(string propName, bool returnNull =false){
            
            propName=propName?.ToUpper();
            
            switch(propName){
                
                default:
                    if(returnNull)
                        return null;

                    throw new ArgumentException("cannot found from NoProp prop "+propName);            

            }
            
            
        }

        public IEnumerable<string> Properties(){
            
            yield break;
        }
        
        
    }

    //[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("RSCG_JSON2Class", "2024.2.29.807")]
    public partial class Test 
    {
        public object GetFromPropertyName(string propName, bool returnNull =false){
            
            propName=propName?.ToUpper();
            
            switch(propName){
                
                case "NUMBER_1234A":
                    return this.Number_1234a ;
                
                default:
                    if(returnNull)
                        return null;

                    throw new ArgumentException("cannot found from Test prop "+propName);            

            }
            
            
        }

        public IEnumerable<string> Properties(){
            
                yield return "Number_1234a" ;
            
            yield break;
        }
        
        [System.Text.Json.Serialization.JsonPropertyName("1234a")]
        public IList<string> Number_1234a { get; set; }
        
        
    }

    //[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("RSCG_JSON2Class", "2024.2.29.807")]
    public partial class Number_55 
    {
        public object GetFromPropertyName(string propName, bool returnNull =false){
            
            propName=propName?.ToUpper();
            
            switch(propName){
                
                case "A":
                    return this.A ;
                
                case "NUMBER_2":
                    return this.Number_2 ;
                
                default:
                    if(returnNull)
                        return null;

                    throw new ArgumentException("cannot found from Number_55 prop "+propName);            

            }
            
            
        }

        public IEnumerable<string> Properties(){
            
                yield return "A" ;
            
                yield return "Number_2" ;
            
            yield break;
        }
        
        [System.Text.Json.Serialization.JsonPropertyName("a")]
        public string A { get; set; }
        
        [System.Text.Json.Serialization.JsonPropertyName("2")]
        public string Number_2 { get; set; }
        
        
    }

    //[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("RSCG_JSON2Class", "2024.2.29.807")]
    public partial class DictData 
    {
        public object GetFromPropertyName(string propName, bool returnNull =false){
            
            propName=propName?.ToUpper();
            
            switch(propName){
                
                case "TEST":
                    return this.Test ;
                
                case "A":
                    return this.A ;
                
                case "NUMBER_2":
                    return this.Number_2 ;
                
                case "MYNUMBER":
                    return this.MyNumber ;
                
                case "NUMBER_55":
                    return this.Number_55 ;
                
                default:
                    if(returnNull)
                        return null;

                    throw new ArgumentException("cannot found from DictData prop "+propName);            

            }
            
            
        }

        public IEnumerable<string> Properties(){
            
                yield return "Test" ;
            
                yield return "A" ;
            
                yield return "Number_2" ;
            
                yield return "MyNumber" ;
            
                yield return "Number_55" ;
            
            yield break;
        }
        
        [System.Text.Json.Serialization.JsonPropertyName("Test")]
        public Test Test { get; set; }
        
        [System.Text.Json.Serialization.JsonPropertyName("A")]
        public string A { get; set; }
        
        [System.Text.Json.Serialization.JsonPropertyName("2")]
        public string Number_2 { get; set; }
        
        [System.Text.Json.Serialization.JsonPropertyName("MyNumber")]
        public int MyNumber { get; set; }
        
        [System.Text.Json.Serialization.JsonPropertyName("55")]
        public Number_55 Number_55 { get; set; }
        
        
    }

    //[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("RSCG_JSON2Class", "2024.2.29.807")]
    public partial class testData 
    {
        public object GetFromPropertyName(string propName, bool returnNull =false){
            
            propName=propName?.ToUpper();
            
            switch(propName){
                
                case "LOGGING":
                    return this.Logging ;
                
                case "PROPCHARS":
                    return this.PropChars ;
                
                case "NOPROP":
                    return this.NoProp ;
                
                case "ALLOWEDHOSTS":
                    return this.AllowedHosts ;
                
                case "MYTEST":
                    return this.MyTest ;
                
                case "DICTDATA":
                    return this.DictData ;
                
                default:
                    if(returnNull)
                        return null;

                    throw new ArgumentException("cannot found from testData prop "+propName);            

            }
            
            
        }

        public IEnumerable<string> Properties(){
            
                yield return "Logging" ;
            
                yield return "PropChars" ;
            
                yield return "NoProp" ;
            
                yield return "AllowedHosts" ;
            
                yield return "MyTest" ;
            
                yield return "DictData" ;
            
            yield break;
        }
        
        [System.Text.Json.Serialization.JsonPropertyName("Logging")]
        public Logging Logging { get; set; }
        
        [System.Text.Json.Serialization.JsonPropertyName("PropChars")]
        public PropChars PropChars { get; set; }
        
        [System.Text.Json.Serialization.JsonPropertyName("NoProp")]
        public NoProp NoProp { get; set; }
        
        [System.Text.Json.Serialization.JsonPropertyName("AllowedHosts")]
        public string AllowedHosts { get; set; }
        
        [System.Text.Json.Serialization.JsonPropertyName("MyTest")]
        public string MyTest { get; set; }
        
        [System.Text.Json.Serialization.JsonPropertyName("DictData")]
        public DictData DictData { get; set; }
        
        
    }

}

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/RSCG_JSON2Class

RSCG – LingoGen

 
 

name LingoGen
nuget https://www.nuget.org/packages/RubenBroere.LingoGen/
link https://github.com/RubenBroere/lingo-gen
author Ruben Broere

Translating from multiple languages

 

This is how you can use LingoGen .

The code that you start with is


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <None Remove="lingo.json" />
  </ItemGroup>

  <ItemGroup>
    <AdditionalFiles Include="lingo.json" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="RubenBroere.LingoGen" Version="0.2.1" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
  </ItemGroup>
	<PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
	</PropertyGroup>
</Project>


The code that you will use is


using System.Globalization;

var name = "Andrei ";

CultureInfo newCulture = new CultureInfo("en");
Thread.CurrentThread.CurrentUICulture = newCulture;

Console.WriteLine(LingoGen.Lingo.Hello_(name));

newCulture = new CultureInfo("fr");
Thread.CurrentThread.CurrentUICulture = newCulture;

Console.WriteLine(LingoGen.Lingo.Hello_(name));

newCulture = new CultureInfo("it");
Thread.CurrentThread.CurrentUICulture = newCulture;

Console.WriteLine(LingoGen.Lingo.Hello_(name));


 

The code that is generated is

// <auto-generated/>


namespace LingoGen;

/// <summary>
/// Static class containing all lingo entries.
/// </summary>
public static partial class Lingo
{

}

// <auto-generated/>

using System;
using System.Globalization;

namespace LingoGen;

public static partial class Lingo
{
    /// <summary>
    /// Hello {Name}
    /// </summary>
    public static string Hello_(string Name) => CultureInfo.CurrentUICulture.TwoLetterISOLanguageName switch
    {
        "it" => $"Buongiorno {Name}",
        "fr" => $"Bonjour {Name}",
        "en" => $"Hello {Name}",
        _ => $"[ No 'Hello_' lingo for '{CultureInfo.CurrentUICulture.TwoLetterISOLanguageName}' ]"
    };
}

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/LingoGen

RSCG – AutoGen

RSCG – AutoGen
 
 

name AutoGen
nuget https://www.nuget.org/packages/Antelcat.AutoGen/
link ,https://github.com/Antelcat/AutoGen
author Feast Antelcat

Generating function to map DTOs

 

This is how you can use AutoGen .

The code that you start with is


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

	<PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
	</PropertyGroup>

	<ItemGroup>
	  <PackageReference Include="Antelcat.AutoGen" Version="1.0.0-pre-alpha-7" />
	</ItemGroup>

	
</Project>


The code that you will use is


using mapperDemo;
var p=new Person();
p.FirstName = "Andrei";
p.LastName = "Ignat";
PersonDTO dto= p.ToDTO();
Console.WriteLine(dto.FullName);




public class Person
{
    public int ID { get; set; }
    public string? FirstName { get; set; }
    public string? LastName { get; set; }
}





using Antelcat.AutoGen.ComponentModel.Mapping;

namespace mapperDemo;
public class PersonDTO
{
    public int ID { get; set; }
    public string? FirstName { get; set; }
    public string? LastName { get; set; }
    [MapIgnore]
    public string FullName { 
        get
        {
            return FirstName + " " + LastName;
        }
    }
}




using Antelcat.AutoGen.ComponentModel.Mapping;

namespace mapperDemo;

public static partial class Extensions
{
    [AutoMap(Extra = [nameof(AfterMap)])]
    public static partial PersonDTO ToDTO(this Person person);

    private static void AfterMap(Person person, PersonDTO personDTO)
    {
        person.ID= personDTO.ID;
    }
}


 

The code that is generated is

// <auto-generated/> By Antelcat.AutoGen
#pragma warning disable
#nullable enable
namespace mapperDemo
{
    partial class Extensions
    {
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Antelcat.AutoGen.SourceGenerators.Generators.Mapping.MapperGenerator", "1.0.0.0")]
        [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute]
        public static partial global::mapperDemo.PersonDTO ToDTO(this global::Person person)
        {
            var ret = new global::mapperDemo.PersonDTO()
            {
                ID = person.ID,
                FirstName = person.FirstName,
                LastName = person.LastName,
            };
            global::mapperDemo.Extensions.AfterMap(person, ret);
            return ret;
        }
    }
}

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/AutoGen

RSCG – RSCG_Wait

RSCG – RSCG_Wait
 
 

name RSCG_Wait
nuget https://www.nuget.org/packages/RSCG_WaitAndOptions/
link https://github.com/ignatandrei/RSCG_WaitAndOptions
author Andrei Ignat

Demo for waiting in compilation and show the options of compiling the code

 

This is how you can use RSCG_Wait .

The code that you start with is


<Project Sdk="Microsoft.NET.Sdk">

	<PropertyGroup>
		<OutputType>Exe</OutputType>
		<TargetFramework>net8.0</TargetFramework>
		<ImplicitUsings>enable</ImplicitUsings>
		<Nullable>enable</Nullable>
		
	</PropertyGroup>
	<ItemGroup>
		<CompilerVisibleProperty Include="RSCG_Wait_Seconds" />
	</ItemGroup>
	<PropertyGroup>
		<RSCG_Wait_Seconds>10</RSCG_Wait_Seconds>
	</PropertyGroup>
	<ItemGroup>
	  <PackageReference Include="RSCG_WaitAndOptions" Version="2024.2.24.1940" 
						OutputItemType="Analyzer" ReferenceOutputAssembly="false" 
						/>
	</ItemGroup>
	<PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
		<GenerateDocumentationFile>True</GenerateDocumentationFile>
	</PropertyGroup>
	
</Project>


The code that you will use is


// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");
Console.WriteLine(RSCG_Wait.MyGeneratedCode.DateStart);
Console.WriteLine(RSCG_Wait.MyGeneratedCode.SecondsToWait);
Console.WriteLine(RSCG_Wait.MyGeneratedCode.DateEnd);
Console.WriteLine(RSCG_Wait.OptionsFromBuild.build_property_projectdir);
Console.WriteLine(RSCG_Wait.OptionsFromBuild.build_property_rootnamespace);
Console.WriteLine(RSCG_Wait.OptionsFromBuild.build_property__supportedplatformlist );


 

The code that is generated is

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool RSCG_Wait.
//     Runtime Version: 2024.2.24.1940
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
//pragma warning disable CS1591
namespace RSCG_Wait;
[global::System.CodeDom.Compiler.GeneratedCode("RSCG_Wait", "2024.2.24.1940")]
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
partial class OptionsFromBuild
{//real name: build_property.rootnamespace
public static string build_property_rootnamespace => @"Console_Wait";
//real name: build_property.projecttypeguids
public static string build_property_projecttypeguids => @"";
//real name: build_property.enforceextendedanalyzerrules
public static string build_property_enforceextendedanalyzerrules => @"";
//real name: build_property.rscg_wait_seconds
public static string build_property_rscg_wait_seconds => @"10";
//real name: build_property.targetframework
public static string build_property_targetframework => @"net8.0";
//real name: build_property.targetplatformminversion
public static string build_property_targetplatformminversion => @"";
//real name: build_property.invariantglobalization
public static string build_property_invariantglobalization => @"";
//real name: build_property.platformneutralassembly
public static string build_property_platformneutralassembly => @"";
//real name: build_property.projectdir
public static string build_property_projectdir => @"D:\gth\RSCG_Examples\v2\rscg_examples\RSCG_Wait\src\Console_Wait\";
//real name: build_property.enablecomhosting
public static string build_property_enablecomhosting => @"";
//real name: build_property.enablegeneratedcominterfacecomimportinterop
public static string build_property_enablegeneratedcominterfacecomimportinterop => @"";
//real name: build_property._supportedplatformlist
public static string build_property__supportedplatformlist => @"Linux,macOS,Windows";
//real name: build_property.usingmicrosoftnetsdkweb
public static string build_property_usingmicrosoftnetsdkweb => @"";
}//end class//end namespace
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool RSCG_Wait.
//     Runtime Version: 2024.2.24.1940
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
//pragma warning disable CS1591
namespace RSCG_Wait;
partial class MyGeneratedCode
{
    public static string DateEnd => "2/24/2024 7:58:07 PM";
    
}
//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool RSCG_Wait.
//     Runtime Version: 2024.2.24.1940
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace RSCG_Wait;
//pragma warning disable CS1591
[global::System.CodeDom.Compiler.GeneratedCode("RSCG_Wait", "2024.2.24.1940")]
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
partial class MyGeneratedCode
{
    public static string DateStart => "2/24/2024 7:57:57 PM";
    public static int SecondsToWait=10;
}
#nullable restore

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/RSCG_Wait

RSCG – PlantUmlClassDiagramGenerator

RSCG – PlantUmlClassDiagramGenerator
 
 

name PlantUmlClassDiagramGenerator
nuget https://www.nuget.org/packages/PlantUmlClassDiagramGenerator.SourceGenerator/
https://www.nuget.org/packages/PlantUmlClassDiagramGenerator.Attributes/
link https://github.com/pierre3/PlantUmlClassDiagramGenerator/
author Hirotada Kobayashi

Generating UML from class definitions

 

This is how you can use PlantUmlClassDiagramGenerator .

The code that you start with is


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <!--<PackageReference Include="PlantUmlClassDiagramGenerator.Attributes" Version="1.3.0.1" />-->
    <PackageReference Include="PlantUmlClassDiagramGenerator.SourceGenerator" Version="0.1.9-alpha">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
  </ItemGroup>

	<PropertyGroup>
	<!--<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">-->
		<DefineConstants>$(DefineConstants);GENERATE_PLANTUML</DefineConstants>
	</PropertyGroup>
	<PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
	</PropertyGroup>
	
	
	
</Project>


The code that you will use is


// See https://aka.ms/new-console-template for more information
using DemoClass2Text;

Person person = new()
{
    FirstName = "Andrei",
    LastName = "Ignat"
};
Console.WriteLine(person.FullName());




namespace DemoClass2Text
{
    [PlantUmlClassDiagramGenerator.SourceGenerator.Attributes.PlantUmlDiagram]
    internal class Person
    {
        public string? FirstName { get; set; }
        public string? LastName { get; set; }
        public string? FullName() => $"{FirstName} {LastName}";
    }
}

 

The code that is generated is

namespace PlantUmlClassDiagramGenerator.SourceGenerator.Attributes;

[System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Interface | System.AttributeTargets.Enum | System.AttributeTargets.Struct)]
internal class PlantUmlDiagramAttribute : System.Attribute
{ }
@startuml Person
class Person  {
    + FirstName : string? <<get>> <<set>>
    + LastName : string? <<get>> <<set>>
    + FullName() : string?
    + Person()
}
@enduml

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/PlantUmlClassDiagramGenerator

RSCG – CopyTo

RSCG – CopyTo
 
 

name CopyTo
nuget https://www.nuget.org/packages/RhoMicro.CodeAnalysis.CopyToGenerator
link https://github.com/PaulBraetz/RhoMicro.CodeAnalysis
author Paul Braetz

Generating copy to code for properties of a class

 

This is how you can use CopyTo .

The code that you start with is


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="RhoMicro.CodeAnalysis.CopyToGenerator" Version="14.0.2">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
  </ItemGroup>
	<PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
	</PropertyGroup>
</Project>


The code that you will use is


using CopyToDemo;

Person p = new();
p.FirstName = "Andrei";
p.LastName = "Ignat";

Person p2 = new();
p.CopyTo(p2);
Console.WriteLine(p2.FullName); 


namespace CopyToDemo;

[RhoMicro.CodeAnalysis.GenerateCopyTo]
internal partial class Person
{
    public string? FirstName { get; set; }
    public string? LastName { get; set; }
    public string FullName => $"{FirstName} {LastName}";
}


 

The code that is generated is

namespace RhoMicro.CodeAnalysis;

using System;

[global::System.AttributeUsage(AttributeTargets.Class)]
#if GENERATOR
[RhoMicro.CodeAnalysis.GenerateFactory]
#endif
internal sealed partial class GenerateCopyToAttribute : global::System.Attribute { }
// <auto-generated>
// This file was last generated by the RhoMicro.CodeAnalysis.CopyToGenerator on 2/18/2024 10:52:42 AM +02:00
// </auto-generated>
#pragma warning disable
namespace CopyToDemo
{
	partial class Person
	{
		/// <summary>
		/// Copies this instances public properties to another ones.
		/// </summary>
		/// <param name = "target">The instance to copy this instances properties' values to.</param>
		public void CopyTo(Person target)
		{
			if (this == target || target == null)
			{
				return;
			}

			if (AvoidCopy(this, target))
			{
				return;
			}

			target.FirstName = this.FirstName;
			target.LastName = this.LastName;
		}

		/// <summary>
		/// Evaluates whether copying between two instances of <see cref = "Person"/> should be avoided due to equivalence. This can help avoid unnecessary copying or infinite copying in nested recursive relationships.
		/// </summary>
		/// <param name = "a">The first instance to compare.</param>
		/// <param name = "b">The second instance to compare.</param>
		/// <param name = "result">Upon returning, contains <see langword="true"/> if copying between <paramref name = "a"/> and <paramref name = "b"/> should be avoided; otherwise, <see langword="false"/>.</param>
		static partial void AvoidCopy(Person a, Person b, ref global::System.Boolean result);
		/// <summary>
		/// Evaluates whether copying between two instances of <see cref = "Person"/> should be avoided due to equivalence. This can help avoid unnecessary copying or infinite copying in nested recursive relationships.
		/// </summary>
		/// <param name = "a">The first instance to compare.</param>
		/// <param name = "b">The second instance to compare.</param>
		/// <returns><see langword="true"/> if copying between <paramref name = "a"/> and <paramref name = "b"/> should be avoided; otherwise, <see langword="false"/>.</returns>
		static global::System.Boolean AvoidCopy(Person a, Person b)
		{
			{
				var result = false;
				AvoidCopy(a, b, ref result);
				return result;
			}
		}
	}
}

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/CopyTo

RSCG – UnionsGenerator

RSCG – UnionsGenerator
 
 

name UnionsGenerator
nuget https://www.nuget.org/packages/RhoMicro.CodeAnalysis.UnionsGenerator
link https://github.com/PaulBraetz/RhoMicro.CodeAnalysis/
author Paul Braetz

Generating Union types for C#

 

This is how you can use UnionsGenerator .

The code that you start with is


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

	<PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
	</PropertyGroup>

	<ItemGroup>
	  <PackageReference Include="RhoMicro.CodeAnalysis.UnionsGenerator" Version="14.0.2">
	    <PrivateAssets>all</PrivateAssets>
	    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
	  </PackageReference>
	</ItemGroup>
</Project>


The code that you will use is


using UnionTypesDemo;

Console.WriteLine("Save or not");
var data = SaveToDatabase.Save(0);
Console.WriteLine(data.IsValidationError);
data = SaveToDatabase.Save(1);
Console.WriteLine(data.IsSuccess);



using RhoMicro.CodeAnalysis;
namespace UnionTypesDemo;
public record Success(int Value);
public record ValidationError(string Message);

[UnionType<Success>]
[UnionTypeAttribute<ValidationError>]
public partial class ResultSave
{
}





namespace UnionTypesDemo;

public class SaveToDatabase
{
    public static ResultSave Save(int i)
    {
        if(i ==0)
        {
            return new ValidationError(" cannot save 0");
        }
        return new Success(i);
    }
}




 

The code that is generated is

// <auto-generated>
// This file was generated by RhoMicro.CodeAnalysis.UnionsGenerator
// The tool used to generate this code may be subject to license terms;
// this generated code is however not subject to those terms, instead it is
// subject to the license (if any) applied to the containing project.
// </auto-generated>
#nullable enable
#pragma warning disable

namespace RhoMicro.CodeAnalysis
{
    using System;

    /// <summary>
    /// Marks the target type to be related to another union type.
    /// </summary>
    /// <typeparam name="T0">The type to register as related to the target union type.</typeparam>
    [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
#if UNIONS_GENERATOR
    [GenerateFactory(OmitTypeCheck = true)]
#endif
    sealed partial class RelationAttribute<T0> : Attribute
    { }
    /// <summary>
    /// Marks the target type to be related to other union types.
    /// </summary>
    /// <typeparam name="T0">The first type to register as related to the target union type.</typeparam>
    /// <typeparam name="T1">The second type to register as related to the target union type.</typeparam>
    [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
    sealed partial class RelationAttribute<T0, T1> : Attribute
    { }
    /// <summary>
    /// Marks the target type to be related to other union types.
    /// </summary>
    /// <typeparam name="T0">The first type to register as related to the target union type.</typeparam>
    /// <typeparam name="T1">The second type to register as related to the target union type.</typeparam>
    /// <typeparam name="T2">The third type to register as related to the target union type.</typeparam>
    [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
    sealed partial class RelationAttribute<T0, T1, T2> : Attribute
    { }
    /// <summary>
    /// Marks the target type to be related to other union types.
    /// </summary>
    /// <typeparam name="T0">The first type to register as related to the target union type.</typeparam>
    /// <typeparam name="T1">The second type to register as related to the target union type.</typeparam>
    /// <typeparam name="T2">The third type to register as related to the target union type.</typeparam>
    /// <typeparam name="T3">The fourth type to register as related to the target union type.</typeparam>
    [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
    sealed partial class RelationAttribute<T0, T1, T2, T3> : Attribute
    { }
    /// <summary>
    /// Marks the target type to be related to other union types.
    /// </summary>
    /// <typeparam name="T0">The first type to register as related to the target union type.</typeparam>
    /// <typeparam name="T1">The second type to register as related to the target union type.</typeparam>
    /// <typeparam name="T2">The third type to register as related to the target union type.</typeparam>
    /// <typeparam name="T3">The fourth type to register as related to the target union type.</typeparam>
    /// <typeparam name="T4">The fifth type to register as related to the target union type.</typeparam>
    [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
    sealed partial class RelationAttribute<T0, T1, T2, T3, T4> : Attribute
    { }
    /// <summary>
    /// Marks the target type to be related to other union types.
    /// </summary>
    /// <typeparam name="T0">The first type to register as related to the target union type.</typeparam>
    /// <typeparam name="T1">The second type to register as related to the target union type.</typeparam>
    /// <typeparam name="T2">The third type to register as related to the target union type.</typeparam>
    /// <typeparam name="T3">The fourth type to register as related to the target union type.</typeparam>
    /// <typeparam name="T4">The fifth type to register as related to the target union type.</typeparam>
    /// <typeparam name="T5">The sixth type to register as related to the target union type.</typeparam>
    [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
    sealed partial class RelationAttribute<T0, T1, T2, T3, T4, T5> : Attribute
    { }
    /// <summary>
    /// Marks the target type to be related to other union types.
    /// </summary>
    /// <typeparam name="T0">The first type to register as related to the target union type.</typeparam>
    /// <typeparam name="T1">The second type to register as related to the target union type.</typeparam>
    /// <typeparam name="T2">The third type to register as related to the target union type.</typeparam>
    /// <typeparam name="T3">The fourth type to register as related to the target union type.</typeparam>
    /// <typeparam name="T4">The fifth type to register as related to the target union type.</typeparam>
    /// <typeparam name="T5">The sixth type to register as related to the target union type.</typeparam>
    /// <typeparam name="T6">The seventh type to register as related to the target union type.</typeparam>
    [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
    sealed partial class RelationAttribute<T0, T1, T2, T3, T4, T5, T6> : Attribute
    { }
    /// <summary>
    /// Marks the target type to be related to other union types.
    /// </summary>
    /// <typeparam name="T0">The first type to register as related to the target union type.</typeparam>
    /// <typeparam name="T1">The second type to register as related to the target union type.</typeparam>
    /// <typeparam name="T2">The third type to register as related to the target union type.</typeparam>
    /// <typeparam name="T3">The fourth type to register as related to the target union type.</typeparam>
    /// <typeparam name="T4">The fifth type to register as related to the target union type.</typeparam>
    /// <typeparam name="T5">The sixth type to register as related to the target union type.</typeparam>
    /// <typeparam name="T6">The seventh type to register as related to the target union type.</typeparam>
    /// <typeparam name="T7">The eighth type to register as related to the target union type.</typeparam>
    [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
    sealed partial class RelationAttribute<T0, T1, T2, T3, T4, T5, T6, T7> : Attribute
    { }
}

// <auto-generated>
// This file was generated by RhoMicro.CodeAnalysis.UnionsGenerator
// The tool used to generate this code may be subject to license terms;
// this generated code is however not subject to those terms, instead it is
// subject to the license (if any) applied to the containing project.
// </auto-generated>
#nullable enable
#pragma warning disable

namespace RhoMicro.CodeAnalysis
{
    using System;

    /// <summary>
    /// Marks the target method as the factory method to use when instantiating 
    /// an instance of the union type representing a value of the annotated parameter.
    /// Factory methods must be static, have no type parameters and only have one 
    /// parameter of a type representable by the union type. 
    /// Factory polymorphism is not yet supported.
    /// </summary>
    [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
#if UNIONS_GENERATOR
    [GenerateFactory]
#endif
    sealed partial class UnionTypeFactoryAttribute : Attribute
    { }
}

// <auto-generated>
// This file was generated by RhoMicro.CodeAnalysis.UnionsGenerator
// The tool used to generate this code may be subject to license terms;
// this generated code is however not subject to those terms, instead it is
// subject to the license (if any) applied to the containing project.
// </auto-generated>
#nullable enable
#pragma warning disable

namespace RhoMicro.CodeAnalysis.UnionsGenerator.Generated
{
    using System.Collections.Concurrent;
    using System.Collections.Generic;
    using System.Text;
    using System.Linq;
    using System;

    [System.CodeDom.Compiler.GeneratedCodeAttribute("RhoMicro.CodeAnalysis.UnionsGenerator", "14.0.2.0")]
    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
    internal static class Util
    {
        private readonly static ConcurrentDictionary<Type, String> _cache = new();
        internal static String GetFullString(Type type) => _cache.GetOrAdd(type, ValueFactory);
        static String ValueFactory(Type type)
        {
            var result = getString(type, new());

            return result;

            static String getString(Type type, StringBuilder builder)
            {
                var unboundTransitiveParameters = 0;
                var transitiveParameters = new List<(String Format, Type? Argument)>();
                append(type, builder, transitiveParameters, ref unboundTransitiveParameters);
                var result = builder.ToString();

                for(var i = 0; i < transitiveParameters.Count; i++)
                {
                    _ = builder.Clear();
                    var (format, argument) = transitiveParameters[i];
                    var replacement = getString(argument!, builder);
                    result = result.Replace(format, replacement);
                }

                return result;

                static void append(
                    Type type,
                    StringBuilder builder,
                    List<(String Format, Type? Argument)> transitiveArgumentsMap,
                    ref Int32 unboundTransitiveParameters)
                {
#if NETSTANDARD2_0
                        if(type.IsGenericParameter && type.DeclaringMethod is null)
#else
                    if(type.IsGenericTypeParameter)
#endif
                    {
                        var format = $"{Guid.NewGuid()}";
                        _ = builder.Append(format);
                        transitiveArgumentsMap.Add((format, null));
                        unboundTransitiveParameters++;
                        return;
                    } else if(type.DeclaringType != null)
                    {
                        append(type.DeclaringType, builder, transitiveArgumentsMap, ref unboundTransitiveParameters);
                        _ = builder.Append('.');
                    } else if(type.Namespace != null)
                    {
                        _ = builder.Append(type.Namespace)
                                .Append('.');
                    }

                    var tickIndex = type.Name.IndexOf('`');
                    _ = tickIndex != -1 ?
#if NETSTANDARD2_0
                            builder.Append(type.Name.Substring(0, tickIndex)) :
#else
                        builder.Append(type.Name.AsSpan(0, tickIndex)) :
#endif
                        builder.Append(type.Name);

                    var arguments = type.GetGenericArguments();
                    var inflectionPoint = unboundTransitiveParameters;
                    if(arguments.Length > 0 && unboundTransitiveParameters > 0)
                    {
                        for(; unboundTransitiveParameters > 0;)
                        {
                            unboundTransitiveParameters--;
                            var (format, _) = transitiveArgumentsMap[unboundTransitiveParameters];
                            transitiveArgumentsMap[unboundTransitiveParameters] = (format, arguments[unboundTransitiveParameters]);
                        }
                    }

                    if(arguments.Length > inflectionPoint)
                    {
                        _ = builder.Append('<');
                        append(arguments[inflectionPoint], builder, transitiveArgumentsMap, ref unboundTransitiveParameters);

                        for(var i = inflectionPoint + 1; i < type.GenericTypeArguments.Length; i++)
                        {
                            _ = builder.Append(", ");
                            append(arguments[i], builder, transitiveArgumentsMap, ref unboundTransitiveParameters);
                        }

                        _ = builder.Append('>');
                    }
                }
            }
        }
        
        internal static System.Boolean IsMarked(Type type) =>
            type.CustomAttributes.Any(a => a.AttributeType.FullName == "RhoMicro.CodeAnalysis.UnionTypeAttribute") ||
            type.GenericTypeArguments.Any(t => t.CustomAttributes.Any(a => 
                a.AttributeType.FullName.StartsWith("RhoMicro.CodeAnalysis.UnionTypeAttribute`") 
                && a.AttributeType.GenericTypeArguments.Length < 255));

        private static readonly System.Collections.Concurrent.ConcurrentDictionary<(Type, Type), Object> _conversionImplementations = new();
        internal static TTo UnsafeConvert<TFrom, TTo>(in TFrom from)
        {
            var impl = (System.Func<TFrom, TTo>)_conversionImplementations.GetOrAdd((typeof(TFrom), typeof(TTo)), k =>
            {
                var param = System.Linq.Expressions.Expression.Parameter(k.Item1);
                var castExpr = System.Linq.Expressions.Expression.Convert(param, k.Item2);
                var lambda = System.Linq.Expressions.Expression.Lambda(castExpr, param).Compile();

                return lambda;
            });
            var result = impl.Invoke(from);

            return result;
        }
    }
}
// <auto-generated>
// This file was generated by RhoMicro.CodeAnalysis.UnionsGenerator
// The tool used to generate this code may be subject to license terms;
// this generated code is however not subject to those terms, instead it is
// subject to the license (if any) applied to the containing project.
// </auto-generated>
#nullable enable
#pragma warning disable

namespace RhoMicro.CodeAnalysis
{
    using System;
    using System.Collections.Generic;

    /// <summary>
    /// Defines options for generating union types.
    /// </summary>
    [Flags]
    enum UnionTypeOptions
    {
        /// <summary>
        /// The default options.
        /// </summary>
        Default = ImplicitConversionIfSolitary,
        /// <summary>
        /// </summary>
        None = 0x00,
        /// <summary>
        /// Instructs the generator to emit an implicit conversion to the representable type if it is the only one.
        /// In effect, this option will enable the union type to act as an alias wrapper for the representable type.
        /// </summary>
        ImplicitConversionIfSolitary = 0x01,
        /// <summary>
        /// Instructs the generator to emit a superset conversion operator implementation even though
        /// the representable type is a generic type parameter. By default, it is omitted because of possible
        /// unification for certain generic arguments.
        /// </summary>
        //SupersetOfParameter = 0x02,
        /// <summary>
        /// Instructs the generator to treat the representable reference type 
        /// as nullable, allowing for <see langword="null"/> 
        /// arguments in factories, conversions etc.
        /// </summary>
        Nullable = 0x04
    }

    /// <summary>
    /// Defines options for the storage implementation of a representable type.
    /// In order for the generator to generate an efficient storage implementation, 
    /// consumers should communicate whether the representable type is known to
    /// be a struct, class or of unknown nature. This is mostly relevant for generic
    /// type parameters, however an explicit strategy may be selected for any representable
    /// type. Whether or not generic type parameters are known to be reference
    /// or value types depends on their constraints. Parameters constrained to 
    /// <see langword="struct"/> will be assumed to be value types. Conversely,
    /// parameters constrained to <see langword="class"/> will be assumed to be reference types.
    /// </summary>
    /*
               | box |value| auto | field
        struct | rc! | vc  | vc   | cc
        class  | rc  | rc! | rc   | cc
        none   | rc! | vc! | rc!  | cc
    */
    enum StorageOption
    {
        /// <summary>
        /// The generator will automatically decide on a storage strategy.
        /// <para>
        /// If the representable type is <b>known to be a value type</b>,
        /// this will store values of that type inside a shared value type container.
        /// <b>Boxing will not occur.</b>
        /// </para>
        /// <para>
        /// If the representable type is <b>known to be a reference type</b>,
        /// this will store values of that type inside a shared reference type container.
        /// </para>
        /// <para>
        /// If the representable type is <b>neither known to be a reference type
        /// nor a value type</b>, this option will cause values of that type to 
        /// be stored inside a shared reference type container.
        /// <b>If the representable type is a generic type parameter,
        /// boxing will occur for value type arguments to that parameter.</b>
        /// </para>
        /// </summary>
        Auto,

        /// <summary>
        /// The generator will always store values of the representable type
        /// inside a shared reference type container.
        /// <para>
        /// If the representable type is <b>known to be a value type</b>,
        /// <b>boxing will occur</b>.
        /// </para>
        /// <para>
        /// If the representable type is a <b>generic type parameter</b>,
        /// <b>boxing will occur for value type arguments</b> to that parameter.
        /// </para>
        /// </summary>
        Reference,

        /// <summary>
        /// The generator will attempt to store values of the representable type
        /// inside a value type container.
        /// <para>
        /// If the representable type is <b>known to be a value type</b>,
        /// this will store values of that type inside a shared value type container.
        /// <b>Boxing will not occur.</b>
        /// </para>
        /// <para>
        /// If the representable type is <b>known to be a reference type</b>,
        /// this will store values of that type inside a shared reference type container.
        /// <b>Boxing will not occur.</b>
        /// </para>
        /// <para>
        /// If the representable type is <b>neither known to be a reference type
        /// nor a value type</b>, this option will cause values of that type to 
        /// be stored inside a shared value type container.
        /// <b>If the representable type is a generic type parameter,
        /// an exception of type <see cref="TypeLoadException"/> will occur for
        /// reference type arguments to that parameter.</b>
        /// </para>
        /// </summary>
        Value,

        /// <summary>
        /// The generator will attempt to store values of the representable type
        /// inside a dedicated container for that type.
        /// <para>
        /// If the representable type is <b>known to be a value type</b>,
        /// this will store values of that type inside a dedicated 
        /// value type container.
        /// <b>Boxing will not occur.</b>
        /// </para>
        /// <para>
        /// If the representable type is <b>known to be a reference type</b>,
        /// this will store values of that type inside a 
        /// dedicated reference type container.
        /// </para>
        /// <para>
        /// If the representable type is <b>neither known to be a reference type
        /// nor a value type</b>, this option will cause values of that type to 
        /// be stored inside a dedicated strongly typed container.
        /// <b>Boxing will not occur.</b>
        /// </para>
        /// </summary>
        Field
    }

    /// <summary>
    /// Marks the target type as a union type being able to represent the type passed to the constructor.
    /// </summary>
    [AttributeUsage(( (AttributeTargets)( -1 ) ))]
    partial class UnionTypeBaseAttribute : Attribute
    {
        /// <summary>
        /// Gets or sets the alias groups that the representable type is to be a part of. 
        /// Represnetable types that share a group may be checked for using unified methods 
        /// and properties like <c>IsGroup</c> where <c>Group</c> is the name of the group
        /// that the representable type is a part of.
        /// </summary>
        public virtual String[] Groups { get; set; } = Array.Empty<String>();

        /// <summary>
        /// Gets or sets the generator options to use.
        /// </summary>
        public virtual UnionTypeOptions Options { get; set; } = UnionTypeOptions.Default;

        /// <summary>
        /// Gets or sets the option defining storage generation.
        /// </summary>
        public virtual StorageOption Storage { get; set; }
    }
    [AttributeUsage(( (AttributeTargets)( -1 ) ))]
#if UNIONS_GENERATOR
    [GenerateFactory(OmitTypeCheck = true)]
#endif
    partial class AliasedUnionTypeBaseAttribute : UnionTypeBaseAttribute
    {
        /// <summary>
        /// Gets or sets the alias to use for members representing the type represented by the union.
        /// For example, the represented type <see cref="List{T}"/> would be represented using names like
        /// <c>list_of_T</c>. Setting this property to <c>yourAlias</c> will instruct the generator to use
        /// member names like <c>yourAlias</c> instead of <c>list_of_T</c>. Use this property to avoid
        /// name collisions in generated code. Since the alias will be used for member names, it will
        /// only be taken into account if it is a valid identifier name.
        /// </summary>
        public String? Alias { get; set; }
        /// <inheritdoc/>
        public override String[] Groups { get => base.Groups; set => base.Groups = value; }
        /// <inheritdoc/>
        public override UnionTypeOptions Options { get => base.Options; set => base.Options = value; }
        /// <inheritdoc/>
        public override StorageOption Storage { get => base.Storage; set => base.Storage = value; }
    }
    /// <summary>
    /// Marks the target type as a union type being able to represent <typeparamref name="T0"/>.
    /// </summary>
    [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
    sealed partial class UnionTypeAttribute<T0> : AliasedUnionTypeBaseAttribute
    { }
    /// <summary>
    /// Marks the target type as a union type being able to represent 
    /// <typeparamref name="T0"/>
    /// and <typeparamref name="T1"/>.
    /// </summary>
    [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
    sealed partial class UnionTypeAttribute<T0, T1> : UnionTypeBaseAttribute
    { }
    /// <summary>
    /// Marks the target type as a union type being able to represent 
    /// <typeparamref name="T0"/>,
    /// <typeparamref name="T1"/>
    /// and <typeparamref name="T2"/>.
    /// </summary>
    [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
    sealed partial class UnionTypeAttribute<T0, T1, T2> : UnionTypeBaseAttribute
    { }
    /// <summary>
    /// Marks the target type as a union type being able to represent 
    /// <typeparamref name="T0"/>,
    /// <typeparamref name="T1"/>,
    /// <typeparamref name="T2"/>
    /// and <typeparamref name="T3"/>.
    /// </summary>
    [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
    sealed partial class UnionTypeAttribute<T0, T1, T2, T3> : UnionTypeBaseAttribute
    { }
    /// <summary>
    /// Marks the target type as a union type being able to represent 
    /// <typeparamref name="T0"/>,
    /// <typeparamref name="T1"/>,
    /// <typeparamref name="T2"/>,
    /// <typeparamref name="T3"/>
    /// and <typeparamref name="T4"/>.
    /// </summary>
    [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
    sealed partial class UnionTypeAttribute<T0, T1, T2, T3, T4> : UnionTypeBaseAttribute
    { }
    /// <summary>
    /// Marks the target type as a union type being able to represent 
    /// <typeparamref name="T0"/>,
    /// <typeparamref name="T1"/>,
    /// <typeparamref name="T2"/>,
    /// <typeparamref name="T3"/>,
    /// <typeparamref name="T4"/>
    /// and <typeparamref name="T5"/>.
    /// </summary>
    [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
    sealed partial class UnionTypeAttribute<T0, T1, T2, T3, T4, T5> : UnionTypeBaseAttribute
    { }
    /// <summary>
    /// Marks the target type as a union type being able to represent 
    /// <typeparamref name="T0"/>,
    /// <typeparamref name="T1"/>,
    /// <typeparamref name="T2"/>,
    /// <typeparamref name="T3"/>,
    /// <typeparamref name="T4"/>,
    /// <typeparamref name="T5"/>
    /// and <typeparamref name="T6"/>.
    /// </summary>
    [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
    sealed partial class UnionTypeAttribute<T0, T1, T2, T3, T4, T5, T6> : UnionTypeBaseAttribute
    { }
    /// <summary>
    /// Marks the target type as a union type being able to represent 
    /// <typeparamref name="T0"/>,
    /// <typeparamref name="T1"/>,
    /// <typeparamref name="T2"/>,
    /// <typeparamref name="T3"/>,
    /// <typeparamref name="T4"/>,
    /// <typeparamref name="T5"/>,
    /// <typeparamref name="T6"/>
    /// and <typeparamref name="T7"/>.
    /// </summary>
    [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
    sealed partial class UnionTypeAttribute<T0, T1, T2, T3, T4, T5, T6, T7> : UnionTypeBaseAttribute
    { }
    /// <summary>
    /// Marks the target type as a union type being able to represent the annotated type parameter.
    /// </summary>
    [AttributeUsage(AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
    sealed partial class UnionTypeAttribute : AliasedUnionTypeBaseAttribute
    { }
}
// <auto-generated>
// This file was generated by RhoMicro.CodeAnalysis.UnionsGenerator
// The tool used to generate this code may be subject to license terms;
// this generated code is however not subject to those terms, instead it is
// subject to the license (if any) applied to the containing project.
// </auto-generated>
#nullable enable
#pragma warning disable

namespace RhoMicro.CodeAnalysis;

using System;

#region Setting Enums
/// <summary>
/// Defines settings for generating an implementation of <see cref="Object.ToString"/>.
/// </summary>
enum ToStringSetting
{
    /// <summary>
    /// The generator will emit an implementation that returns detailed information, including:
    /// <list type="bullet">
    /// <item><description>the name of the union type</description></item>
    /// <item><description>a list of types representable by the union type</description></item>
    /// <item><description>an indication of which type is being represented by the instance</description></item>
    /// <item><description>the value currently being represented by the instance</description></item>
    /// </list>
    /// </summary>
    Detailed,
    /// <summary>
    /// The generator will not generate an implementation of <see cref="Object.ToString"/>.
    /// </summary>
    None,
    /// <summary>
    /// The generator will generate an implementation that returns the result of calling <see cref="Object.ToString"/> on the currently represented value.
    /// </summary>
    Simple
}
/// <summary>
/// Defines settings for annotating the target with an instance of <see cref="System.Runtime.InteropServices.StructLayoutAttribute"/>.
/// </summary>
enum LayoutSetting
{
    /// <summary>
    /// Generate an annotation optimized for size.
    /// </summary>
    Small,
    /// <summary>
    /// Do not generate any annotations.
    /// </summary>
    Auto
}
/// <summary>
/// Defines settings for controlling the accessibility of generated constructors.
/// </summary>
enum ConstructorAccessibilitySetting
{
    /// <summary>
    /// Generated constructors should always be private, unless
    /// no conversion operators are generated for the type they
    /// accept. This would be the case for interface types or
    /// supertypes of the target union.
    /// </summary>
    PublicIfInconvertible,
    /// <summary>
    /// Generated constructors should always be private.
    /// </summary>
    Private,
    /// <summary>
    /// Generated constructors should always be public
    /// </summary>
    Public
}
/// <summary>
/// Defines settings on how to implement interfaces that all representable
/// types implement.
/// </summary>
enum InterfaceMatchSetting
{
    /// <summary>
    /// Generated interface implementations should be explicit if at least
    /// one of the representable types implements the interface explicitly;
    /// otherwise, interface implementations should be implicit.
    /// </summary>
    Auto,
    /// <summary>
    /// Generated interface implementations should always be explicit.
    /// </summary>
    Explicit,
    /// <summary>
    /// Generated interface implementations should always be implicit.
    /// </summary>
    Implicit,
    /// <summary>
    /// No interfaces implementations should be generated.
    /// </summary>
    Omit
}
/// <summary>
/// Defines settings for the kind of diagnostics to report.
/// </summary>
[Flags]
enum DiagnosticsLevelSettings
{
    /// <summary>
    /// Instructs the analyzer not to emit diagnostics
    /// </summary>
    None = 0x00,
    /// <summary>
    /// Instructs the analyzer to report info diagnostics.
    /// </summary>
    Info = 0x01,
    /// <summary>
    /// Instructs the analyzer to report warning diagnostics.
    /// </summary>
    Warning = 0x02,
    /// <summary>
    /// Instructs the analyzer to report error diagnostics.
    /// </summary>
    Error = 0x04,
    /// <summary>
    /// Instructs the analyzer to report all diagnostics.
    /// </summary>
    All = Info | Warning | Error
}
/// <summary>
/// Defines miscellaneous settings.
/// </summary>
[Flags]
enum MiscellaneousSettings
{
    /// <summary>
    /// </summary>
    None = 0x00,
    /// <summary>
    /// The default settings.
    /// </summary>
    Default = None,
    /// <summary>
    /// Indicates whether the generated source code should be available as a string constant on the union type itself.
    /// This setting is generally only useful if the generated implementation should be emitted from another generator.
    /// </summary>
    EmitGeneratedSourceCode = 0x01,
    /// <summary>
    /// Indicates whether to generate a custom converter type 
    /// for <c>System.Text.Json</c> deserialization. If set, this will also cause
    /// the union type to be annotated with an appropriate <c>JsonConverter</c> attribute.
    /// </summary>
    GenerateJsonConverter = 0x02,
    /// <summary>
    /// Indicates that the generator should emit a comment detailing the structure of the union type.
    /// </summary>
    EmitStructuralRepresentation = 0x04
}

/// <summary>
/// Defines settings pertaining to equality operator implementations.
/// </summary>
enum EqualityOperatorsSetting
{
    /// <summary>
    /// Equality operators will be emitted only if the target union type is a value type.
    /// </summary>
    EmitOperatorsIfValueType,
    /// <summary>
    /// Equality operators will be emitted.
    /// </summary>
    EmitOperators,
    /// <summary>
    /// Equality operators will be omitted.
    /// </summary>
    OmitOperators
}

#endregion
#region Attribute Declaration
/// <summary>
/// Supplies the generator with additional settings on how to generate a targeted union type.
/// If the target member is an assembly, the attribute supplies default values for any union 
/// type setting not defined.
/// </summary>
[AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class | AttributeTargets.Assembly, AllowMultiple = false, Inherited = false)]
#if UNIONS_GENERATOR
[GenerateFactory]
#endif
sealed partial class UnionTypeSettingsAttribute : Attribute
{
    #region Settings
    /// <summary>
    /// Defines how to generate an implementation <see cref="Object.ToString"/>.
    /// </summary>
    public ToStringSetting ToStringSetting { get; set; } = ToStringSetting.Detailed;
    /// <summary>
    /// Defines whether to generate a size optimizing annotation.
    /// </summary>
    public LayoutSetting Layout { get; set; } = LayoutSetting.Auto;
    /// <summary>
    /// The level of diagnostics to be reported by the analyzer.
    /// </summary>
    public DiagnosticsLevelSettings DiagnosticsLevel { get; set; } = DiagnosticsLevelSettings.All;
    /// <summary>
    /// The desired accessibility of generated constructors.
    /// </summary>
    public ConstructorAccessibilitySetting ConstructorAccessibility { get; set; } = ConstructorAccessibilitySetting.Private;
    /// <summary>
    /// Indicates how to generate implementations for
    /// interfaces implemented by all representable types. Implementations will 
    /// map calls to interface instance methods and properties onto the represented
    /// value. 
    /// <para>
    /// Please note that currently, only fully bound and constructed interface implementations are supported.
    /// </para>
    /// </summary>
    public InterfaceMatchSetting InterfaceMatchSetting { get; set; } = InterfaceMatchSetting.Auto;
    /// <summary>
    /// Indicates how to generate equality operators.
    /// By default, equality operators will only be emitted for value types, so as to preserve
    /// reference equality for comparing reference union types via <c>==</c> or <c>!=</c>.
    /// </summary>
    public EqualityOperatorsSetting EqualityOperatorsSetting { get; set; } = EqualityOperatorsSetting.EmitOperatorsIfValueType;
    /// <summary>
    /// Gets or sets miscellaneous settings.
    /// </summary>
    public MiscellaneousSettings Miscellaneous { get; set; } = MiscellaneousSettings.Default;
    #endregion
    #region Strings
    /// <summary>
    /// A raw code preface to prepend before the generated type declaration.
    /// </summary>
    public String TypeDeclarationPreface { get; set; } = "";
    /// <summary>
    /// The name of the generic parameter for generic <c>Is</c>, <c>As</c> and factory methods. 
    /// Set this property in order to avoid name collisions with generic union type parameters
    /// </summary>
    public String GenericTValueName { get; set; } = "TValue";
    /// <summary>
    /// The name of the generic parameter for the <c>TryConvert</c> method. 
    /// Set this property in order to avoid name collisions with generic union type parameters
    /// </summary>
    public String TryConvertTypeName { get; set; } = "TUnion";
    /// <summary>
    /// The name of the generic parameter for the <c>Match</c> method. 
    /// Set this property in order to avoid name collisions with generic union type parameters
    /// </summary>
    public String MatchTypeName { get; set; } = "TMatchResult";
    /// <summary>
    /// The name to use for the discriminating tag type.
    /// </summary>
    public String TagTypeName { get; set; } = "__Tag";
    /// <summary>
    /// The name to use for the container type containing value types.
    /// </summary>
    public String ValueTypeContainerTypeName { get; set; } = "__ValueTypeContainer";
    /// <summary>
    /// The name to use for the field containing value types.
    /// </summary>
    public String ValueTypeContainerName { get; set; } = "__value";
    /// <summary>
    /// The name to use for the field containing reference types.
    /// </summary>
    public String ReferenceTypeContainerName { get; set; } = "__reference";
    /// <summary>
    /// The name to use for the field containing the discriminating tag.
    /// </summary>
    public String TagFieldName { get; set; } = "__tag";
    /// <summary>
    /// The name to use for the default (uninitialized) tag value.
    /// </summary>
    public String TagNoneName { get; set; } = "__None";
    /// <summary>
    /// The name of the generated json converter type.
    /// </summary>
    public String JsonConverterTypeName { get; set; } = "JsonConverter";
    #endregion
}
#endregion
// <auto-generated>
// This file was last generated by RhoMicro.CodeAnalysis.UnionsGenerator at 2/18/2024 10:51:57 AM +02:00
// The tool used to generate this code may be subject to license terms;
// this generated code is however not subject to those terms, instead it is
// subject to the license (if any) applied to the containing project.
// </auto-generated>
#pragma warning disable
#nullable enable
#region Implementation of UnionTypesDemo.ResultSave
namespace UnionTypesDemo
{
	using System.Linq;
	
	#region Scoped Data
	file static class UnionTypesDemo_ResultSave_ScopedData
	{
		public static System.Collections.Concurrent.ConcurrentDictionary<System.Type, System.Object> Cache { get; } = new();
		public static System.Collections.Generic.HashSet<System.Type> RepresentableTypes { get; } = 
		new ()
		{
			typeof(UnionTypesDemo.Success),
			typeof(UnionTypesDemo.ValidationError)
		}
		;
	}
	#endregion
	partial class ResultSave : System.IEquatable<ResultSave?>
	{
		
		#region Nested Types
		#region Value Type Container
		#endregion
		#region Tag Type
		/// <summary>
		/// Defines tags to discriminate between representable types.
		/// </summary>
		/// <remarks>
		/// This member is not intended for use by user code inside of or any code outside of <see cref="UnionTypesDemo.ResultSave"/>.
		/// </remarks>
		[System.CodeDom.Compiler.GeneratedCodeAttribute("RhoMicro.CodeAnalysis.UnionsGenerator", "14.0.2.0")]
		[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
		private enum __Tag : System.Byte
		{
			/// <summary>
			/// Used when not representing any type due to e.g. incorrect or missing initialization.
			/// </summary>
			__None,

			
			/// <summary>
			/// Used when representing an instance of <see cref="UnionTypesDemo.Success"/>.
			/// </summary>
			Success,
			
			/// <summary>
			/// Used when representing an instance of <see cref="UnionTypesDemo.ValidationError"/>.
			/// </summary>
			ValidationError
		}
		#endregion
		#endregion
		
		#region Constructors
		
		/// <summary>
		/// Creates a new instance of <see cref="UnionTypesDemo.ResultSave"/>representing an instance of <see cref="UnionTypesDemo.Success"/>.
		/// </summary>
		[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
		[System.CodeDom.Compiler.GeneratedCodeAttribute("RhoMicro.CodeAnalysis.UnionsGenerator", "14.0.2.0")]
		private ResultSave(UnionTypesDemo.Success value)
		{
			__tag = __Tag.Success;
			this.__reference = value;
		}
		
		
		/// <summary>
		/// Creates a new instance of <see cref="UnionTypesDemo.ResultSave"/>representing an instance of <see cref="UnionTypesDemo.ValidationError"/>.
		/// </summary>
		[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
		[System.CodeDom.Compiler.GeneratedCodeAttribute("RhoMicro.CodeAnalysis.UnionsGenerator", "14.0.2.0")]
		private ResultSave(UnionTypesDemo.ValidationError value)
		{
			__tag = __Tag.ValidationError;
			this.__reference = value;
		}
		#endregion
		
		#region Fields
		
		/// <summary>
		/// Contains the value of instances of <see cref="UnionTypesDemo.ResultSave"/> representing one of these types:
		/// <list type="bullet">
		/// <item>
		/// <see cref="UnionTypesDemo.Success"/>
		/// </item>
		/// <item>
		/// <see cref="UnionTypesDemo.ValidationError"/>
		/// </item>
		/// </list>
		/// </summary>
		/// <remarks>
		/// This member is not intended for use by user code inside of or any code outside of <see cref="UnionTypesDemo.ResultSave"/>.
		/// </remarks>
		[System.CodeDom.Compiler.GeneratedCodeAttribute("RhoMicro.CodeAnalysis.UnionsGenerator", "14.0.2.0")]
		[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
		private readonly System.Object? __reference;
		
		/// <summary>
		/// Used to determine the currently represented type and value.
		/// </summary>
		/// <remarks>
		/// This member is not intended for use by user code inside of or any code outside of <see cref="UnionTypesDemo.ResultSave"/>.
		/// </remarks>
		[System.CodeDom.Compiler.GeneratedCodeAttribute("RhoMicro.CodeAnalysis.UnionsGenerator", "14.0.2.0")]
		[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
		private readonly __Tag __tag;
		#endregion
		
		#region Factories
		
		/// <summary>
		/// Creates a new instance of <see cref="UnionTypesDemo.ResultSave"/> representing an instance of <see cref="UnionTypesDemo.Success"/>.
		/// </summary>
		/// <param name="value">
		/// The value to be represented by the new instance of <see cref="UnionTypesDemo.ResultSave"/>.
		/// </param>
		/// <returns>
		/// A new instance of <see cref="UnionTypesDemo.ResultSave"/> representing <paramref name="value"/>.
		/// </returns>
		public static ResultSave CreateFromSuccess([RhoMicro.CodeAnalysis.UnionTypeFactory]UnionTypesDemo.Success value) => new(value);
		
		/// <summary>
		/// Creates a new instance of <see cref="UnionTypesDemo.ResultSave"/> representing an instance of <see cref="UnionTypesDemo.ValidationError"/>.
		/// </summary>
		/// <param name="value">
		/// The value to be represented by the new instance of <see cref="UnionTypesDemo.ResultSave"/>.
		/// </param>
		/// <returns>
		/// A new instance of <see cref="UnionTypesDemo.ResultSave"/> representing <paramref name="value"/>.
		/// </returns>
		public static ResultSave CreateFromValidationError([RhoMicro.CodeAnalysis.UnionTypeFactory]UnionTypesDemo.ValidationError value) => new(value);
		/// <summary>
		/// Attempts to create an instance of <see cref="UnionTypesDemo.ResultSave"/> from an instance of <typeparamref name="TValue"/>.
		/// </summary>
		/// <param name="value">
		/// The value from which to attempt to create an instance of <see cref="UnionTypesDemo.ResultSave"/>.
		/// </param>
		/// <param name="result">
		/// If an instance of <see cref="UnionTypesDemo.ResultSave"/> could successfully be created, this parameter will contain the newly created instance; otherwise, <see langword="default"/>.
		/// </param>
		/// <returns>
		/// <see langword="true"/> if an instance of <see cref="UnionTypesDemo.ResultSave"/> could successfully be created; otherwise, <see langword="false"/>.
		/// </returns>
		public static System.Boolean TryCreate<TValue>(TValue value, [System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out ResultSave? result)
		{
			var metadataName = RhoMicro.CodeAnalysis.UnionsGenerator.Generated.Util.GetFullString(typeof(TValue));
			switch(metadataName)
			{
				case "UnionTypesDemo.Success":
				{
					result = CreateFromSuccess((RhoMicro.CodeAnalysis.UnionsGenerator.Generated.Util.UnsafeConvert<TValue, UnionTypesDemo.Success>(value)));
					return true;
				}
				
				case "UnionTypesDemo.ValidationError":
				{
					result = CreateFromValidationError((RhoMicro.CodeAnalysis.UnionsGenerator.Generated.Util.UnsafeConvert<TValue, UnionTypesDemo.ValidationError>(value)));
					return true;
				}
				default:
				{
					
					{
						var sourceType = typeof(TValue);
						if(!UnionTypesDemo_ResultSave_ScopedData.Cache.TryGetValue(sourceType, out var weakMatch))
						{
							if(!RhoMicro.CodeAnalysis.UnionsGenerator.Generated.Util.IsMarked(sourceType))
							{
								result = default;
								return false;
							}
							weakMatch = UnionTypesDemo_ResultSave_ScopedData.Cache.GetOrAdd(sourceType, t =>
							{
								var tupleType = typeof(System.ValueTuple<System.Boolean, ResultSave>);
								var matchMethod = sourceType.GetMethod(nameof(Match), System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public)
									?.MakeGenericMethod(tupleType) ??
									throw new System.InvalidOperationException("Unable to locate match function on source union type. This indicates a bug in the marker detection algorithm.");
								var targetFactoryMap = typeof(UnionTypesDemo.ResultSave).GetMethods()
									.Where(c => c.CustomAttributes.Any(a => a.AttributeType.FullName == "RhoMicro.CodeAnalysis.UnionTypeFactoryAttribute"))
									.ToDictionary(c => c.GetParameters()[0].ParameterType);
								var handlers = matchMethod.GetParameters()
									.Select(p => p.ParameterType.GenericTypeArguments[0])
									.Select(t => (ParameterExpr: System.Linq.Expressions.Expression.Parameter(t), ParameterExprType: t))
									.Select(t =>
									{
										var delegateType = typeof(System.Func<,>).MakeGenericType(t.ParameterExprType, tupleType);
										System.Linq.Expressions.Expression expression = targetFactoryMap.TryGetValue(t.ParameterExprType, out var factory)
											? System.Linq.Expressions.Expression.New(tupleType.GetConstructors()[0], System.Linq.Expressions.Expression.Constant(true), System.Linq.Expressions.Expression.Call(factory, t.ParameterExpr))
											: System.Linq.Expressions.Expression.Default(tupleType);
										return System.Linq.Expressions.Expression.Lambda(delegateType, expression, t.ParameterExpr);
									}
									);var paramExpr = System.Linq.Expressions.Expression.Parameter(sourceType);
								var callExpr = System.Linq.Expressions.Expression.Call(paramExpr, matchMethod, handlers);
								var lambdaExpr = System.Linq.Expressions.Expression.Lambda(callExpr, paramExpr);
								var result = lambdaExpr.Compile();
								return result;
							}
							);
						}
						var match = (System.Func<TValue, (System.Boolean, UnionTypesDemo.ResultSave)>)weakMatch;
						var matchResult = match.Invoke(value);
						if(!matchResult.Item1)
						{
							result = default;
							return false;
						}
						result = matchResult.Item2;
						return true;
					}
				}
			}
		}
		/// <summary>
		/// Creates an instance of <see cref="UnionTypesDemo.ResultSave"/> from an instance of <typeparamref name="TValue"/>.
		/// </summary>
		/// <param name="value">
		/// The value from which to create an instance of <see cref="UnionTypesDemo.ResultSave"/>.
		/// </param>
		/// <returns>
		/// A new instance of <see cref="UnionTypesDemo.ResultSave"/> representing <paramref name="value"/>.
		/// </returns>
		public static ResultSave Create<TValue>(TValue value)
		{
			var metadataName = RhoMicro.CodeAnalysis.UnionsGenerator.Generated.Util.GetFullString(typeof(TValue));
			switch(metadataName)
			{
				case "UnionTypesDemo.Success":
				{
					return CreateFromSuccess((RhoMicro.CodeAnalysis.UnionsGenerator.Generated.Util.UnsafeConvert<TValue, UnionTypesDemo.Success>(value)));
				}
				
				case "UnionTypesDemo.ValidationError":
				{
					return CreateFromValidationError((RhoMicro.CodeAnalysis.UnionsGenerator.Generated.Util.UnsafeConvert<TValue, UnionTypesDemo.ValidationError>(value)));
				}
				default:
				{
					
					{
						var sourceType = typeof(TValue);
						if(!UnionTypesDemo_ResultSave_ScopedData.Cache.TryGetValue(sourceType, out var weakMatch))
						{
							if(!RhoMicro.CodeAnalysis.UnionsGenerator.Generated.Util.IsMarked(sourceType))
							{
								throw new System.InvalidOperationException($"Unable to create an instance of UnionTypesDemo.ResultSave from an instance of {typeof(TValue)}.");
							}
							weakMatch = UnionTypesDemo_ResultSave_ScopedData.Cache.GetOrAdd(sourceType, t =>
							{
								var tupleType = typeof(System.ValueTuple<System.Boolean, ResultSave>);
								var matchMethod = sourceType.GetMethod(nameof(Match), System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public)
									?.MakeGenericMethod(tupleType) ??
									throw new System.InvalidOperationException("Unable to locate match function on source union type. This indicates a bug in the marker detection algorithm.");
								var targetFactoryMap = typeof(UnionTypesDemo.ResultSave).GetMethods()
									.Where(c => c.CustomAttributes.Any(a => a.AttributeType.FullName == "RhoMicro.CodeAnalysis.UnionTypeFactoryAttribute"))
									.ToDictionary(c => c.GetParameters()[0].ParameterType);
								var handlers = matchMethod.GetParameters()
									.Select(p => p.ParameterType.GenericTypeArguments[0])
									.Select(t => (ParameterExpr: System.Linq.Expressions.Expression.Parameter(t), ParameterExprType: t))
									.Select(t =>
									{
										var delegateType = typeof(System.Func<,>).MakeGenericType(t.ParameterExprType, tupleType);
										System.Linq.Expressions.Expression expression = targetFactoryMap.TryGetValue(t.ParameterExprType, out var factory)
											? System.Linq.Expressions.Expression.New(tupleType.GetConstructors()[0], System.Linq.Expressions.Expression.Constant(true), System.Linq.Expressions.Expression.Call(factory, t.ParameterExpr))
											: System.Linq.Expressions.Expression.Default(tupleType);
										return System.Linq.Expressions.Expression.Lambda(delegateType, expression, t.ParameterExpr);
									}
									);var paramExpr = System.Linq.Expressions.Expression.Parameter(sourceType);
								var callExpr = System.Linq.Expressions.Expression.Call(paramExpr, matchMethod, handlers);
								var lambdaExpr = System.Linq.Expressions.Expression.Lambda(callExpr, paramExpr);
								var result = lambdaExpr.Compile();
								return result;
							}
							);
						}
						var match = (System.Func<TValue, (System.Boolean, UnionTypesDemo.ResultSave)>)weakMatch;
						var matchResult = match.Invoke(value);
						if(!matchResult.Item1)
						{
							throw new System.InvalidOperationException($"Unable to create an instance of UnionTypesDemo.ResultSave from an instance of {typeof(TValue)}.");
						}
						return matchResult.Item2;
					}
				}
			}
		}
		#endregion
		
		#region Switch
		/// <summary>
		/// Invokes a handler based on the type of value being represented.
		/// </summary>
		/// <param name="onSuccess">
		/// The handler to invoke if the union is currently representing an instance of <see cref="UnionTypesDemo.Success"/>.
		/// </param>
		/// <param name="onValidationError">
		/// The handler to invoke if the union is currently representing an instance of <see cref="UnionTypesDemo.ValidationError"/>.
		/// </param>
		public void Switch(
			System.Action<UnionTypesDemo.Success> onSuccess,
			System.Action<UnionTypesDemo.ValidationError> onValidationError)
		{
			switch(this.__tag)
			{
				case __Tag.Success:
				{
					onSuccess.Invoke(((UnionTypesDemo.Success)this.__reference!));
					return;
				}
				
				case __Tag.ValidationError:
				{
					onValidationError.Invoke(((UnionTypesDemo.ValidationError)this.__reference!));
					return;
				}
				
				default:
				{
					throw new System.InvalidOperationException("Unable to determine the represented type or value. The union type was likely not initialized correctly.");
				}
			}
		}
		#endregion
		
		#region Match
		/// <summary>
		/// Invokes a projection based on the type of value being represented.
		/// </summary>
		/// <param name="onSuccess">
		/// The projection to invoke if the union is currently representing an instance of <see cref="UnionTypesDemo.Success"/>.
		/// </param>
		/// <param name="onValidationError">
		/// The projection to invoke if the union is currently representing an instance of <see cref="UnionTypesDemo.ValidationError"/>.
		/// </param>
		/// <typeparam name="TMatchResult">
		/// The type of value produced by the projections passed.
		/// </typeparam>
		/// <returns>
		/// The projected value.
		/// </returns>
		public TMatchResult Match<TMatchResult>(
			System.Func<UnionTypesDemo.Success, TMatchResult> onSuccess,
			System.Func<UnionTypesDemo.ValidationError, TMatchResult> onValidationError) =>
		this.__tag switch
		{
			__Tag.Success => onSuccess.Invoke(((UnionTypesDemo.Success)this.__reference!))
			,
			__Tag.ValidationError => onValidationError.Invoke(((UnionTypesDemo.ValidationError)this.__reference!))
			,
			_ => throw new System.InvalidOperationException("Unable to determine the represented type or value. The union type was likely not initialized correctly.")
		}
		;
		#endregion
		
		#region Represented Type
		/// <summary>
		/// Gets the types of value this union type can represent.
		/// </summary>
		public static System.Collections.Generic.IReadOnlyCollection<System.Type> RepresentableTypes { get; } = 
			UnionTypesDemo_ResultSave_ScopedData.RepresentableTypes;
		/// <summary>
		/// Gets the type of value represented by this instance.
		/// </summary>
		public System.Type RepresentedType => 
		this.__tag switch
		{
			__Tag.Success => typeof(UnionTypesDemo.Success),
			__Tag.ValidationError => typeof(UnionTypesDemo.ValidationError),
			_ => throw new System.InvalidOperationException("Unable to determine the represented type or value. The union type was likely not initialized correctly.")
		}
		;
		#endregion
		
		#region Is/As Properties
		
		/// <summary>
		/// Gets a value indicating whether this instance is representing a value of type <see cref="UnionTypesDemo.Success"/>.
		/// </summary>
		public System.Boolean IsSuccess => __tag == __Tag.Success;
		
		/// <summary>
		/// Gets a value indicating whether this instance is representing a value of type <see cref="UnionTypesDemo.ValidationError"/>.
		/// </summary>
		public System.Boolean IsValidationError => __tag == __Tag.ValidationError;
		
		/// <summary>
		/// Retrieves the value represented by this instance as a <see cref="UnionTypesDemo.Success"/>.
		/// </summary>
		public UnionTypesDemo.Success? AsSuccess => __tag == __Tag.Success
		? ((UnionTypesDemo.Success)this.__reference!)
		: null;
		
		/// <summary>
		/// Retrieves the value represented by this instance as a <see cref="UnionTypesDemo.ValidationError"/>.
		/// </summary>
		public UnionTypesDemo.ValidationError? AsValidationError => __tag == __Tag.ValidationError
		? ((UnionTypesDemo.ValidationError)this.__reference!)
		: null;
		#endregion
		
		#region Is Group Properties
		
		#endregion
		
		#region Is/As Functions
		
		/// <summary>
		/// Determines whether this instance is representing a value of type <see cref="UnionTypesDemo.Success"/>.
		/// </summary>
		/// <returns>
		/// <see langword="true"/> if this instance is representing a value of type <see cref="UnionTypesDemo.Success"/>; otherwise, <see langword="false"/>.
		/// </returns>
		/// <param name="value">
		/// If this instance is representing a value of type <see cref="UnionTypesDemo.Success"/>, this parameter will contain that value; otherwise, <see langword="default"/>.
		/// </param>
		public System.Boolean TryAsSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out UnionTypesDemo.Success value)
		{
			if(this.__tag == __Tag.Success)
			{
				value = ((UnionTypesDemo.Success)this.__reference!);
				return true;
			}
			value = default;
			return false;
		}
		
		/// <summary>
		/// Determines whether this instance is representing a value of type <see cref="UnionTypesDemo.ValidationError"/>.
		/// </summary>
		/// <returns>
		/// <see langword="true"/> if this instance is representing a value of type <see cref="UnionTypesDemo.ValidationError"/>; otherwise, <see langword="false"/>.
		/// </returns>
		/// <param name="value">
		/// If this instance is representing a value of type <see cref="UnionTypesDemo.ValidationError"/>, this parameter will contain that value; otherwise, <see langword="default"/>.
		/// </param>
		public System.Boolean TryAsValidationError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out UnionTypesDemo.ValidationError value)
		{
			if(this.__tag == __Tag.ValidationError)
			{
				value = ((UnionTypesDemo.ValidationError)this.__reference!);
				return true;
			}
			value = default;
			return false;
		}
		/// <summary>
		/// Determines whether this instance is representing a value of type <typeparamref name="TValue"/>.
		/// </summary>
		/// <typeparam name="TValue">
		/// The type whose representation in this instance to determine.
		/// </typeparam>
		/// <returns>
		/// <see langword="true"/> if this instance is representing a value of type <typeparamref name="TValue"/>; otherwise, <see langword="false"/>.
		/// </returns>
		public System.Boolean Is<TValue>() =>typeof(TValue) ==this.__tag switch
		{
			__Tag.Success => typeof(UnionTypesDemo.Success),
			__Tag.ValidationError => typeof(UnionTypesDemo.ValidationError),
			_ => throw new System.InvalidOperationException("Unable to determine the represented type or value. The union type was likely not initialized correctly.")
		}
		;
		/// <summary>
		/// Determines whether this instance is representing a value of type <typeparamref name="TValue"/>.
		/// </summary>
		/// <param name="value">
		/// If this instance is representing a value of type <typeparamref name="TValue"/>, this parameter will contain that value; otherwise, <see langword="default"/>.
		/// </param>
		/// <typeparam name="TValue">
		/// The type whose representation in this instance to determine.
		/// </typeparam>
		/// <returns>
		/// <see langword="true"/> if this instance is representing a value of type <typeparamref name="TValue"/>; otherwise, <see langword="false"/>.
		/// </returns>
		public System.Boolean Is<TValue>(out TValue? value)
		{
			var metadataName = RhoMicro.CodeAnalysis.UnionsGenerator.Generated.Util.GetFullString(typeof(TValue));
			switch(metadataName)
			{
				case "UnionTypesDemo.Success":
				{
					value = (RhoMicro.CodeAnalysis.UnionsGenerator.Generated.Util.UnsafeConvert<UnionTypesDemo.Success, TValue>((UnionTypesDemo.Success)this.__reference!));
					return true;
				}
				
				case "UnionTypesDemo.ValidationError":
				{
					value = (RhoMicro.CodeAnalysis.UnionsGenerator.Generated.Util.UnsafeConvert<UnionTypesDemo.ValidationError, TValue>((UnionTypesDemo.ValidationError)this.__reference!));
					return true;
				}
				default:
				{
					
					{
						value = default;
						return false;
					}
				}
			}
		}
		/// <summary>
		/// Determines whether this instance is representing an instance of <paramref name="type"/>.
		/// </summary>
		/// <param name="type">
		/// The type whose representation in this instance to determine.
		/// </param>
		/// <returns>
		/// <see langword="true"/> if this instance is representing an instance of <paramref name="type"/>; otherwise, <see langword="false"/>.
		/// </returns>
		public System.Boolean Is(System.Type type) =>
		type == this.__tag switch
		{
			__Tag.Success => typeof(UnionTypesDemo.Success),
			__Tag.ValidationError => typeof(UnionTypesDemo.ValidationError),
			_ => throw new System.InvalidOperationException("Unable to determine the represented type or value. The union type was likely not initialized correctly.")
		}
		;
		/// <summary>
		/// Retrieves the value represented by this instance as an instance of <typeparamref name="TValue"/>.
		/// </summary>
		/// <typeparam name="TValue">
		/// The type to retrieve the represented value as.
		/// </typeparam>
		/// <returns>
		/// The currently represented value as an instance of <typeparamref name="TValue"/>.
		/// </returns>
		public TValue As<TValue>() =>
		this.__tag switch
		{
			__Tag.Success => typeof(TValue) == typeof(UnionTypesDemo.Success)
			? (RhoMicro.CodeAnalysis.UnionsGenerator.Generated.Util.UnsafeConvert<UnionTypesDemo.Success, TValue>((UnionTypesDemo.Success)this.__reference!))
			: throw new System.InvalidOperationException($"Unable to convert from an instance of {typeof(UnionTypesDemo.ResultSave)} representing a value of type {this.RepresentedType} to an instance of {typeof(TValue)}."),
			__Tag.ValidationError => typeof(TValue) == typeof(UnionTypesDemo.ValidationError)
			? (RhoMicro.CodeAnalysis.UnionsGenerator.Generated.Util.UnsafeConvert<UnionTypesDemo.ValidationError, TValue>((UnionTypesDemo.ValidationError)this.__reference!))
			: throw new System.InvalidOperationException($"Unable to convert from an instance of {typeof(UnionTypesDemo.ResultSave)} representing a value of type {this.RepresentedType} to an instance of {typeof(TValue)}."),
			_ => throw new System.InvalidOperationException("Unable to determine the represented type or value. The union type was likely not initialized correctly.")
		}
		;
		#endregion
		
		#region ToString
		/// <inheritdoc/>
		public override System.String ToString()
		{
			var stringRepresentation = this.__tag switch
			{
				__Tag.Success => ((this.__reference!)?.ToString() ?? System.String.Empty),
				__Tag.ValidationError => ((this.__reference!)?.ToString() ?? System.String.Empty),
				_ => throw new System.InvalidOperationException("Unable to determine the represented type or value. The union type was likely not initialized correctly.")
			}
			;
			var result = $"ResultSave({(__tag == __Tag.Success ? "<Success>" : "Success")}|{(__tag == __Tag.ValidationError ? "<ValidationError>" : "ValidationError")}){{{stringRepresentation}}}";
			return result;
		}
		#endregion
		
		#region GetHashCode
		/// <inheritdoc/>
		public override System.Int32 GetHashCode() => 
		this.__tag switch
		{
			__Tag.Success => (System.Collections.Generic.EqualityComparer<UnionTypesDemo.Success>.Default.GetHashCode(((UnionTypesDemo.Success)this.__reference!))),
			__Tag.ValidationError => (System.Collections.Generic.EqualityComparer<UnionTypesDemo.ValidationError>.Default.GetHashCode(((UnionTypesDemo.ValidationError)this.__reference!))),
			_ => throw new System.InvalidOperationException("Unable to determine the represented type or value. The union type was likely not initialized correctly.")
		}
		;
		#endregion
		
		#region Equality
		/// <inheritdoc/>
		public override System.Boolean Equals(System.Object? obj) =>
			obj is ResultSave union && Equals(union);
		/// <inheritdoc/>
		public System.Boolean Equals(ResultSave? other) =>
			ReferenceEquals(other, this)
			|| other != null
			&& this.__tag == other.__tag
			&& this.__tag switch
			{
				__Tag.Success => (System.Collections.Generic.EqualityComparer<UnionTypesDemo.Success>.Default.Equals(((UnionTypesDemo.Success)this.__reference!), ((UnionTypesDemo.Success)other.__reference!))),
				__Tag.ValidationError => (System.Collections.Generic.EqualityComparer<UnionTypesDemo.ValidationError>.Default.Equals(((UnionTypesDemo.ValidationError)this.__reference!), ((UnionTypesDemo.ValidationError)other.__reference!))),
				_ => throw new System.InvalidOperationException("Unable to determine the represented type or value. The union type was likely not initialized correctly.")
			}
			;
		
		#endregion
		
		#region Conversions
		
		#region Representable Type Conversions
		
		/// <summary>
		/// Converts an instance of the representable type <see cref="UnionTypesDemo.Success"/> to the union type <see cref="UnionTypesDemo.ResultSave"/>.
		/// </summary>
		/// <param name="value">
		/// The value to convert.
		/// </param>
		/// <returns>
		/// The union type instance.
		/// </returns>
		public static implicit operator ResultSave(UnionTypesDemo.Success value) => CreateFromSuccess(value);
		/// <summary>
		/// Converts an instance of the union type <see cref="UnionTypesDemo.ResultSave"/> to the representable type <see cref="UnionTypesDemo.Success"/>.
		/// </summary>
		/// <param name="union">
		/// The union to convert.
		/// </param>
		/// <returns>
		/// The represented value.
		/// </returns>
		public static explicit operator UnionTypesDemo.Success(UnionTypesDemo.ResultSave union) =>union.__tag == __Tag.Success?
		((UnionTypesDemo.Success)union.__reference!):throw new System.InvalidOperationException($"Unable to convert from an instance of {typeof(ResultSave)} representing a value of type {union.RepresentedType} to an instance of {typeof(UnionTypesDemo.Success)}.");
		
		/// <summary>
		/// Converts an instance of the representable type <see cref="UnionTypesDemo.ValidationError"/> to the union type <see cref="UnionTypesDemo.ResultSave"/>.
		/// </summary>
		/// <param name="value">
		/// The value to convert.
		/// </param>
		/// <returns>
		/// The union type instance.
		/// </returns>
		public static implicit operator ResultSave(UnionTypesDemo.ValidationError value) => CreateFromValidationError(value);
		/// <summary>
		/// Converts an instance of the union type <see cref="UnionTypesDemo.ResultSave"/> to the representable type <see cref="UnionTypesDemo.ValidationError"/>.
		/// </summary>
		/// <param name="union">
		/// The union to convert.
		/// </param>
		/// <returns>
		/// The represented value.
		/// </returns>
		public static explicit operator UnionTypesDemo.ValidationError(UnionTypesDemo.ResultSave union) =>union.__tag == __Tag.ValidationError?
		((UnionTypesDemo.ValidationError)union.__reference!):throw new System.InvalidOperationException($"Unable to convert from an instance of {typeof(ResultSave)} representing a value of type {union.RepresentedType} to an instance of {typeof(UnionTypesDemo.ValidationError)}.");
		#endregion
		
		#region Related Type Conversions
		#endregion
		#endregion
	}
}
#endregion

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/UnionsGenerator

RSCG – corecraft

RSCG – corecraft
 
 

name corecraft
nuget https://www.nuget.org/packages/corecraft/
link https://github.com/AlexNav73/CoreCraft
author

Decomposing properties and class into Domain Models. Seems however too complicated to use

 

This is how you can use corecraft .

The code that you start with is


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
	<PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
	</PropertyGroup>
	<ItemGroup>
	  <None Remove="Person.model.json" />
	</ItemGroup>
	<ItemGroup>
	  <AdditionalFiles Include="Person.model.json">
	    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
	  </AdditionalFiles>
	</ItemGroup>
	<ItemGroup>
	  <PackageReference Include="CoreCraft" Version="0.6.0" />
	  <PackageReference Include="CoreCraft.Generators" Version="0.6.0">
	    <PrivateAssets>all</PrivateAssets>
	    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
	  </PackageReference>
	</ItemGroup>
</Project>


The code that you will use is


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
	<PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
	</PropertyGroup>
	<ItemGroup>
	  <None Remove="Person.model.json" />
	</ItemGroup>
	<ItemGroup>
	  <AdditionalFiles Include="Person.model.json">
	    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
	  </AdditionalFiles>
	</ItemGroup>
	<ItemGroup>
	  <PackageReference Include="CoreCraft" Version="0.6.0" />
	  <PackageReference Include="CoreCraft.Generators" Version="0.6.0">
	    <PrivateAssets>all</PrivateAssets>
	    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
	  </PackageReference>
	</ItemGroup>
</Project>



using CoreCraft;
using CoreCraft.ChangesTracking;
using CoreCraft.Subscription;
using Json2Code.Person;
using Json2Code.Person.Entities;
var model = new DomainModel(new[] { new Json2Code.Person.PersonShardModelShard() });

// Subscribe to Items collection change events 
using var subscription = model.For<IPersonShardChangesFrame>()
    .With(x => x.Persons)
    .Subscribe(OnItemChanged);

// Observe changes
void OnItemChanged(Change<ICollectionChangeSet<Person, PersonProperties>> changes)
{
    foreach (var c in changes.Hunk)
    {
        Console.WriteLine($"Entity [{c.Entity}] has been {c.Action}ed.");
        Console.WriteLine($"   Old data: {c.OldData}");
        Console.WriteLine($"   New data: {c.NewData}");
    }
}


await model.Run<IMutablePersonShardModelShard> (
    (shard, _) =>
    {
        shard.Persons.Add(new() { FirstName = "A", LastName = "B" });
        //shard.Persons.Remove(shard.Persons.First());
    });
await model.Run<IMutablePersonShardModelShard>(
    (shard, _) =>
    {        
        shard.Persons.Modify(shard.Persons.First(), p => p with { FirstName = "C" });
    });

await model.Run<IMutablePersonShardModelShard>(
    (shard, _) =>
    {
        shard.Persons.Remove(shard.Persons.First());
    });



Console.WriteLine("Press any key to exit...");
Console.ReadKey();



{
  "shards": [
    {
      "name": "PersonShard",
      "entities": [
        {
          "name": "Person",
          "properties": [
            {
              "name": "FirstName",
              "type": "string",
              "defaultValue": "\"Andrei\""
            },
            {
              "name": "LastName",
              "type": "string",
              "defaultValue": "\"Ignat\""
            }
          ]
        }
      ],
      "collections": [
        {
          "name": "Persons",
          "entityType": "Person"
        }
      ],
      "relations": []
    }
  ]
}

 

The code that is generated is


//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by the tool.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

#nullable enable

namespace Json2Code.Person
{
    using CoreCraft.Core;
    using CoreCraft.ChangesTracking;
    using CoreCraft.Persistence;
    using Json2Code.Person.Entities;

    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("C# Source Generator", "1.0.0.0")]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    public interface IPersonShardModelShard : IModelShard
    {
        ICollection<Person, PersonProperties> Persons { get; }

    }

    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("C# Source Generator", "1.0.0.0")]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    public interface IMutablePersonShardModelShard : IModelShard
    {
        IMutableCollection<Person, PersonProperties> Persons { get; }

    }

    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("C# Source Generator", "1.0.0.0")]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute()]
    internal static class PersonShardModelShardInfo
    {
        public static readonly CollectionInfo PersonsInfo = new("PersonShard", "Persons", new PropertyInfo[] { new("FirstName", typeof(string), false), new("LastName", typeof(string), false) });

    }

    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("C# Source Generator", "1.0.0.0")]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute()]
    internal sealed partial class PersonShardModelShard : IPersonShardModelShard
    {
        public const string PersonsId = "Json2Code.Person.PersonShard.Persons";

        public PersonShardModelShard()
        {
            Persons = new Collection<Person, PersonProperties>(
                PersonsId,
                static id => new Person(id),
                static () => new PersonProperties());

        }

        internal PersonShardModelShard(IMutablePersonShardModelShard mutable)
        {
            Persons = ((IMutableState<ICollection<Person, PersonProperties>>)mutable.Persons).AsReadOnly();

        }

        public ICollection<Person, PersonProperties> Persons { get; init; } = null!;

    }

    internal sealed partial class PersonShardModelShard : IReadOnlyState<IMutablePersonShardModelShard>
    {
        public IMutablePersonShardModelShard AsMutable(global::System.Collections.Generic.IEnumerable<IFeature> features)
        {
            var persons = (IMutableCollection<Person, PersonProperties>)Persons;


            foreach (var feature in features)
            {
                persons = feature.Decorate(this, persons);

            }

            return new MutablePersonShardModelShard()
            {
                Persons = persons,

            };
        }
    }

    internal sealed partial class PersonShardModelShard : ICanBeSaved
    {
        public void Save(IRepository repository)
        {
            repository.Save(PersonShardModelShardInfo.PersonsInfo, Persons);

        }
    }

    internal sealed partial class PersonShardModelShard : IFeatureContext
    {
        IChangesFrame IFeatureContext.GetOrAddFrame(IMutableModelChanges modelChanges)
        {
            return modelChanges.Register(static () => new PersonShardChangesFrame());
        }
    }

    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("C# Source Generator", "1.0.0.0")]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    public interface IPersonShardChangesFrame : IChangesFrame
    {
        ICollectionChangeSet<Person, PersonProperties> Persons { get; }

    }

    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("C# Source Generator", "1.0.0.0")]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute()]
    internal sealed class PersonShardChangesFrame : IPersonShardChangesFrame, IChangesFrameEx, ICanBeSaved
    {
        public PersonShardChangesFrame()
        {
            Persons = new CollectionChangeSet<Person, PersonProperties>(PersonShardModelShard.PersonsId);

        }

        public ICollectionChangeSet<Person, PersonProperties> Persons { get; private set; }


        ICollectionChangeSet<TEntity, TProperty>? IChangesFrame.Get<TEntity, TProperty>(ICollection<TEntity, TProperty> collection)
        {
            if (Persons.Id == collection.Id) return Persons as ICollectionChangeSet<TEntity, TProperty>;

            throw new System.InvalidOperationException("Unable to find collection's changes set");
        }

        IRelationChangeSet<TParent, TChild>? IChangesFrame.Get<TParent, TChild>(IRelation<TParent, TChild> relation)
        {

            throw new System.InvalidOperationException($"Unable to find relation's change set");
        }

        IChangesFrame IChangesFrame.Invert()
        {
            return new PersonShardChangesFrame()
            {
                Persons = Persons.Invert(),

            };
        }

        public void Apply(IModel model)
        {
            var modelShard = model.Shard<IMutablePersonShardModelShard>();

            Persons.Apply(modelShard.Persons);
        }

        public bool HasChanges()
        {
            return Persons.HasChanges();
        }

        public IChangesFrame Merge(IChangesFrame frame)
        {
            var typedFrame = (PersonShardChangesFrame)frame;

            return new PersonShardChangesFrame()
            {
                Persons = Persons.Merge(typedFrame.Persons),

            };
        }

        public void Save(IRepository repository)
        {
            repository.Save(PersonShardModelShardInfo.PersonsInfo, Persons);

        }

    }

    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("C# Source Generator", "1.0.0.0")]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute()]
    internal sealed class MutablePersonShardModelShard : IMutablePersonShardModelShard, IMutableState<IPersonShardModelShard>, ICanBeLoaded
    {
        public IMutableCollection<Person, PersonProperties> Persons { get; init; } = null!;


        public IPersonShardModelShard AsReadOnly()
        {
            return new PersonShardModelShard(this);
        }

        public void Load(IRepository repository)
        {
            repository.Load(PersonShardModelShardInfo.PersonsInfo, Persons);

        }
    }

}

namespace Json2Code.Person.Entities
{
    using CoreCraft.Core;

    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("C# Source Generator", "1.0.0.0")]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute()]
    public sealed record Person(global::System.Guid Id) : Entity(Id)
    {
        internal Person() : this(global::System.Guid.NewGuid())
        {
        }
    }

    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("C# Source Generator", "1.0.0.0")]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute()]
    public sealed partial record PersonProperties : Properties
    {
        public PersonProperties()
        {
            FirstName = "Andrei";
            LastName = "Ignat";
        }

        public string FirstName { get; init; }
        public string LastName { get; init; }

#if NET5_0_OR_GREATER
        public override PersonProperties ReadFrom(IPropertiesBag bag)
#else
        public override Properties ReadFrom(IPropertiesBag bag)
#endif
        {
            return new PersonProperties()
            {
                FirstName = bag.Read<string>("FirstName"),
                LastName = bag.Read<string>("LastName"),
            };
        }

        public override void WriteTo(IPropertiesBag bag)
        {
            bag.Write("FirstName", FirstName);
            bag.Write("LastName", LastName);
        }

    }


}

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/corecraft

RSCG – sourcedepend

RSCG – sourcedepend
 
 

name sourcedepend
nuget https://www.nuget.org/packages/sourcedepend/
link https://github.com/crwsolutions/sourcedepend
author Colin Wilmans

Generating constructor for DI

 

This is how you can use sourcedepend .

The code that you start with is


<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

	<PropertyGroup>
		<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
		<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
	</PropertyGroup>

	<ItemGroup>
	  <PackageReference Include="SourceDepend" Version="0.3.0" />
	</ItemGroup>

</Project>


The code that you will use is


using CtorDemo;

var p = new Person("Andrei", "Ignat");

Console.WriteLine(p.FullName());



namespace CtorDemo;
internal partial class Person
{
    [Dependency]
    public readonly string? FirstName;
    [Dependency]
    public readonly string? LastName;
    
    public string FullName() => $"{FirstName} {LastName}";

    partial void PostConstruct()
    {
        Console.WriteLine("Person constructed");
    }
    partial void PreConstruct()
    {
        Console.WriteLine("Person constructing");
    }

}


 

The code that is generated is

// <auto-generated />

/// <summary>
/// Injects this item in the constructor. This will also highjack your constructor, so if you have any construct business, use PreConstruct() or PostConstruct() methods.
/// </summary>
/// <remarks>
/// Make sure your class is partial.
/// </remarks>
[System.AttributeUsage(System.AttributeTargets.Field | System.AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
[System.Diagnostics.Conditional("DependencyGenerator_DEBUG")]
internal sealed class DependencyAttribute : System.Attribute
{
    internal DependencyAttribute(string alternativePropertyName = null) { }
}

// <auto-generated/>
#pragma warning disable
#nullable enable
namespace CtorDemo
{
    /// <inheritdoc/>
    internal partial class Person
    {
        public Person(string? FirstName, string? LastName)
        {
            PreConstruct();

            this.FirstName = FirstName;
            this.LastName = LastName;

            PostConstruct();
        }

        partial void PreConstruct();
        partial void PostConstruct();
    }
}

Code and pdf at

https://ignatandrei.github.io/RSCG_Examples/v2/docs/sourcedepend

Andrei Ignat weekly software news(mostly .NET)

* indicates required

Please select all the ways you would like to hear from me:

You can unsubscribe at any time by clicking the link in the footer of our emails. For information about our privacy practices, please visit our website.

We use Mailchimp as our marketing platform. By clicking below to subscribe, you acknowledge that your information will be transferred to Mailchimp for processing. Learn more about Mailchimp's privacy practices here.