diff --git a/README.md b/README.md index 952fa21..c31d796 100644 --- a/README.md +++ b/README.md @@ -42,14 +42,21 @@ public partial class FooResult ``` Or you can use generic type. ```csharp -[GenericUnionType] -public partial class OperationDataResult +public partial class OperationDataResult<[GenericUnionType] TResult, [GenericUnionType] TError> { } // extend generic type union with additional Int32 type [UnionType(typeof(int))] -public partial class ExtendedOperationDataResult +public partial class ExtendedOperationDataResult<[GenericUnionType] TResult, [GenericUnionType] TError> +{ +} +``` +Null values are not allowed by default. This behavior can be overriden by `AllowNull = true` parameter. +```csharp +[UnionType(typeof(int?), AllowNull = true)] +[UnionType(typeof(string), AllowNull = true)] +public partial class ResultNullable<[GenericUnionType(AllowNull = true)] T> { } ``` diff --git a/examples/DataAccess/DataAccessModel.cs b/examples/DataAccess/DataAccessModel.cs index 154d157..97b61f8 100644 --- a/examples/DataAccess/DataAccessModel.cs +++ b/examples/DataAccess/DataAccessModel.cs @@ -2,9 +2,6 @@ namespace DataAccess; - -// TODO - uncomment to negative case -// --> public record DataAccessModel1; public record DataAccessModel2(string Message); @@ -15,6 +12,5 @@ public partial class DataAccessModel { } -// <-- public record DataAccessModel3(); \ No newline at end of file diff --git a/examples/N.SourceGenerators.UnionTypes.Examples/Program.cs b/examples/N.SourceGenerators.UnionTypes.Examples/Program.cs index a095012..f5bdc59 100644 --- a/examples/N.SourceGenerators.UnionTypes.Examples/Program.cs +++ b/examples/N.SourceGenerators.UnionTypes.Examples/Program.cs @@ -81,14 +81,13 @@ public partial class Result2 { } -[GenericUnionType] -public partial class OperationDataResult +public partial class OperationDataResult<[GenericUnionType] TResult, [GenericUnionType] TError> { } // extend generic type union with additional Int32 type [UnionType(typeof(int))] -public partial class ExtendedOperationDataResult +public partial class ExtendedOperationDataResult<[GenericUnionType] TResult, [GenericUnionType] TError> { } diff --git a/src/N.SourceGenerators.UnionTypes.Benchmark/README.md b/src/N.SourceGenerators.UnionTypes.Benchmark/README.md index 5cc9224..41cfe2b 100644 --- a/src/N.SourceGenerators.UnionTypes.Benchmark/README.md +++ b/src/N.SourceGenerators.UnionTypes.Benchmark/README.md @@ -1,88 +1,88 @@ ## Ctor ``` ini -BenchmarkDotNet=v0.13.4, OS=Windows 11 (10.0.22621.1105) -Intel Core i7-1065G7 CPU 1.30GHz, 1 CPU, 8 logical and 4 physical cores -.NET SDK=7.0.102 - [Host] : .NET 7.0.2 (7.0.222.60605), X64 RyuJIT AVX2 - Job-BKNSSQ : .NET 7.0.2 (7.0.222.60605), X64 RyuJIT AVX2 +BenchmarkDotNet=v0.13.4, OS=macOS 14.0 (23A344) [Darwin 23.0.0] +Apple M2 Max, 1 CPU, 12 logical and 12 physical cores +.NET SDK=7.0.401 + [Host] : .NET 7.0.11 (7.0.1123.42427), Arm64 RyuJIT AdvSIMD + Job-CPQSKY : .NET 7.0.11 (7.0.1123.42427), Arm64 RyuJIT AdvSIMD Runtime=.NET 7.0 Toolchain=net7.0 IterationCount=3 LaunchCount=1 WarmupCount=3 ``` -| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio | -|----------------------------- |---------:|----------:|----------:|------:|--------:|-------:|----------:|------------:| -| Class | 7.050 ns | 0.3546 ns | 0.0194 ns | 1.00 | 0.00 | 0.0153 | 64 B | 1.00 | -| ClassSealed | 6.769 ns | 2.5824 ns | 0.1416 ns | 0.96 | 0.02 | 0.0153 | 64 B | 1.00 | -| Struct | 3.302 ns | 0.5208 ns | 0.0285 ns | 0.47 | 0.00 | 0.0057 | 24 B | 0.38 | -| StructReadonly | 3.264 ns | 0.6143 ns | 0.0337 ns | 0.46 | 0.00 | 0.0057 | 24 B | 0.38 | -| StructExplicitLayout | 4.123 ns | 0.5004 ns | 0.0274 ns | 0.58 | 0.00 | - | - | 0.00 | -| StructReadonlyExplicitLayout | 4.115 ns | 0.8700 ns | 0.0477 ns | 0.58 | 0.01 | - | - | 0.00 | +| Method | Mean | Error | StdDev | Ratio | Gen0 | Allocated | Alloc Ratio | +|----------------------------- |----------:|----------:|----------:|------:|-------:|----------:|------------:| +| Class | 6.0429 ns | 0.2688 ns | 0.0147 ns | 1.000 | 0.0086 | 72 B | 1.00 | +| ClassSealed | 6.0265 ns | 0.2679 ns | 0.0147 ns | 0.997 | 0.0086 | 72 B | 1.00 | +| Struct | 2.4038 ns | 0.2048 ns | 0.0112 ns | 0.398 | 0.0029 | 24 B | 0.33 | +| StructReadonly | 2.4161 ns | 0.2119 ns | 0.0116 ns | 0.400 | 0.0029 | 24 B | 0.33 | +| StructExplicitLayout | 0.0000 ns | 0.0000 ns | 0.0000 ns | 0.000 | - | - | 0.00 | +| StructReadonlyExplicitLayout | 0.0000 ns | 0.0000 ns | 0.0000 ns | 0.000 | - | - | 0.00 | ## GetHashCode ``` ini -BenchmarkDotNet=v0.13.4, OS=Windows 11 (10.0.22621.1105) -Intel Core i7-1065G7 CPU 1.30GHz, 1 CPU, 8 logical and 4 physical cores -.NET SDK=7.0.102 - [Host] : .NET 7.0.2 (7.0.222.60605), X64 RyuJIT AVX2 - Job-EOFGDV : .NET 7.0.2 (7.0.222.60605), X64 RyuJIT AVX2 +BenchmarkDotNet=v0.13.4, OS=macOS 14.0 (23A344) [Darwin 23.0.0] +Apple M2 Max, 1 CPU, 12 logical and 12 physical cores +.NET SDK=7.0.401 + [Host] : .NET 7.0.11 (7.0.1123.42427), Arm64 RyuJIT AdvSIMD + Job-MVTOFC : .NET 7.0.11 (7.0.1123.42427), Arm64 RyuJIT AdvSIMD Runtime=.NET 7.0 Toolchain=net7.0 IterationCount=3 LaunchCount=1 WarmupCount=3 ``` -| Method | Mean | Error | StdDev | Ratio | RatioSD | Allocated | Alloc Ratio | -|----------------------------- |----------:|----------:|----------:|------:|--------:|----------:|------------:| -| Class | 6.758 ns | 0.5807 ns | 0.0318 ns | 1.00 | 0.00 | - | NA | -| ClassSealed | 6.731 ns | 0.7423 ns | 0.0407 ns | 1.00 | 0.01 | - | NA | -| Struct | 12.645 ns | 2.8756 ns | 0.1576 ns | 1.87 | 0.02 | - | NA | -| StructReadonly | 12.605 ns | 1.5499 ns | 0.0850 ns | 1.87 | 0.01 | - | NA | -| StructExplicitLayout | 2.465 ns | 0.1746 ns | 0.0096 ns | 0.36 | 0.00 | - | NA | -| StructReadonlyExplicitLayout | 2.315 ns | 0.7554 ns | 0.0414 ns | 0.34 | 0.01 | - | NA | +| Method | Mean | Error | StdDev | Ratio | Allocated | Alloc Ratio | +|----------------------------- |---------:|----------:|----------:|------:|----------:|------------:| +| Class | 4.119 ns | 0.0605 ns | 0.0033 ns | 1.00 | - | NA | +| ClassSealed | 4.133 ns | 0.0484 ns | 0.0027 ns | 1.00 | - | NA | +| Struct | 7.660 ns | 0.1243 ns | 0.0068 ns | 1.86 | - | NA | +| StructReadonly | 7.677 ns | 0.2665 ns | 0.0146 ns | 1.86 | - | NA | +| StructExplicitLayout | 1.467 ns | 0.0200 ns | 0.0011 ns | 0.36 | - | NA | +| StructReadonlyExplicitLayout | 1.470 ns | 0.0193 ns | 0.0011 ns | 0.36 | - | NA | ## ReadValue ``` ini -BenchmarkDotNet=v0.13.4, OS=Windows 11 (10.0.22621.1105) -Intel Core i7-1065G7 CPU 1.30GHz, 1 CPU, 8 logical and 4 physical cores -.NET SDK=7.0.102 - [Host] : .NET 7.0.2 (7.0.222.60605), X64 RyuJIT AVX2 - Job-RVTMNA : .NET 7.0.2 (7.0.222.60605), X64 RyuJIT AVX2 +BenchmarkDotNet=v0.13.4, OS=macOS 14.0 (23A344) [Darwin 23.0.0] +Apple M2 Max, 1 CPU, 12 logical and 12 physical cores +.NET SDK=7.0.401 + [Host] : .NET 7.0.11 (7.0.1123.42427), Arm64 RyuJIT AdvSIMD + Job-NCEFIQ : .NET 7.0.11 (7.0.1123.42427), Arm64 RyuJIT AdvSIMD Runtime=.NET 7.0 Toolchain=net7.0 IterationCount=3 LaunchCount=1 WarmupCount=3 ``` -| Method | Mean | Error | StdDev | Ratio | RatioSD | Allocated | Alloc Ratio | -|----------------------------- |---------:|----------:|----------:|------:|--------:|----------:|------------:| -| Class | 1.674 ns | 0.2215 ns | 0.0121 ns | 1.00 | 0.00 | - | NA | -| ClassSealed | 1.675 ns | 0.8915 ns | 0.0489 ns | 1.00 | 0.02 | - | NA | -| Struct | 6.576 ns | 1.2893 ns | 0.0707 ns | 3.93 | 0.05 | - | NA | -| StructReadonly | 6.749 ns | 2.4536 ns | 0.1345 ns | 4.03 | 0.07 | - | NA | -| StructExplicitLayout | 1.727 ns | 1.0336 ns | 0.0567 ns | 1.03 | 0.03 | - | NA | -| StructReadonlyExplicitLayout | 1.636 ns | 0.1580 ns | 0.0087 ns | 0.98 | 0.01 | - | NA | +| Method | Mean | Error | StdDev | Ratio | RatioSD | Allocated | Alloc Ratio | +|----------------------------- |----------:|----------:|----------:|------:|--------:|----------:|------------:| +| Class | 0.3540 ns | 0.0891 ns | 0.0049 ns | 1.00 | 0.00 | - | NA | +| ClassSealed | 0.3228 ns | 0.0092 ns | 0.0005 ns | 0.91 | 0.01 | - | NA | +| Struct | 3.2880 ns | 0.2043 ns | 0.0112 ns | 9.29 | 0.15 | - | NA | +| StructReadonly | 3.2877 ns | 0.0631 ns | 0.0035 ns | 9.29 | 0.13 | - | NA | +| StructExplicitLayout | 0.2804 ns | 0.0901 ns | 0.0049 ns | 0.79 | 0.02 | - | NA | +| StructReadonlyExplicitLayout | 0.3270 ns | 1.9317 ns | 0.1059 ns | 0.92 | 0.30 | - | NA | ## ToString ``` ini -BenchmarkDotNet=v0.13.4, OS=Windows 11 (10.0.22621.1105) -Intel Core i7-1065G7 CPU 1.30GHz, 1 CPU, 8 logical and 4 physical cores -.NET SDK=7.0.102 - [Host] : .NET 7.0.2 (7.0.222.60605), X64 RyuJIT AVX2 - Job-PKSHPT : .NET 7.0.2 (7.0.222.60605), X64 RyuJIT AVX2 +BenchmarkDotNet=v0.13.4, OS=macOS 14.0 (23A344) [Darwin 23.0.0] +Apple M2 Max, 1 CPU, 12 logical and 12 physical cores +.NET SDK=7.0.401 + [Host] : .NET 7.0.11 (7.0.1123.42427), Arm64 RyuJIT AdvSIMD + Job-MVCCVK : .NET 7.0.11 (7.0.1123.42427), Arm64 RyuJIT AdvSIMD Runtime=.NET 7.0 Toolchain=net7.0 IterationCount=3 LaunchCount=1 WarmupCount=3 ``` -| Method | Mean | Error | StdDev | Ratio | Gen0 | Allocated | Alloc Ratio | -|----------------------------- |---------:|----------:|---------:|------:|-------:|----------:|------------:| -| Class | 95.39 ns | 10.200 ns | 0.559 ns | 1.00 | 0.1128 | 472 B | 1.00 | -| ClassSealed | 90.89 ns | 7.331 ns | 0.402 ns | 0.95 | 0.1128 | 472 B | 1.00 | -| Struct | 99.57 ns | 10.057 ns | 0.551 ns | 1.04 | 0.1128 | 472 B | 1.00 | -| StructReadonly | 98.63 ns | 17.335 ns | 0.950 ns | 1.03 | 0.1128 | 472 B | 1.00 | -| StructExplicitLayout | 94.54 ns | 5.686 ns | 0.312 ns | 0.99 | 0.1147 | 480 B | 1.02 | -| StructReadonlyExplicitLayout | 95.61 ns | 11.132 ns | 0.610 ns | 1.00 | 0.1147 | 480 B | 1.02 | +| Method | Mean | Error | StdDev | Ratio | Gen0 | Allocated | Alloc Ratio | +|----------------------------- |---------:|---------:|---------:|------:|-------:|----------:|------------:| +| Class | 72.75 ns | 0.173 ns | 0.009 ns | 1.00 | 0.0564 | 472 B | 1.00 | +| ClassSealed | 72.83 ns | 2.486 ns | 0.136 ns | 1.00 | 0.0564 | 472 B | 1.00 | +| Struct | 77.59 ns | 3.612 ns | 0.198 ns | 1.07 | 0.0564 | 472 B | 1.00 | +| StructReadonly | 76.85 ns | 2.708 ns | 0.148 ns | 1.06 | 0.0564 | 472 B | 1.00 | +| StructExplicitLayout | 70.28 ns | 4.734 ns | 0.260 ns | 0.97 | 0.0573 | 480 B | 1.02 | +| StructReadonlyExplicitLayout | 71.65 ns | 1.785 ns | 0.098 ns | 0.98 | 0.0573 | 480 B | 1.02 | diff --git a/src/N.SourceGenerators.UnionTypes/Extensions/ConditionalSyntaxExtensions.cs b/src/N.SourceGenerators.UnionTypes/Extensions/ConditionalSyntaxExtensions.cs index 027a8c6..51714eb 100644 --- a/src/N.SourceGenerators.UnionTypes/Extensions/ConditionalSyntaxExtensions.cs +++ b/src/N.SourceGenerators.UnionTypes/Extensions/ConditionalSyntaxExtensions.cs @@ -115,4 +115,14 @@ public static ParameterSyntax AddModifiersWhen( ? syntax.AddModifiers(items) : syntax; } + + public static ParameterSyntax AddAttributeListsWhen( + this ParameterSyntax syntax, + bool condition, + params AttributeListSyntax[] items) + { + return condition + ? syntax.AddAttributeLists(items) + : syntax; + } } \ No newline at end of file diff --git a/src/N.SourceGenerators.UnionTypes/Extensions/SyntaxNodeExtensions.cs b/src/N.SourceGenerators.UnionTypes/Extensions/SyntaxNodeExtensions.cs index 6d82a03..e5fbc01 100644 --- a/src/N.SourceGenerators.UnionTypes/Extensions/SyntaxNodeExtensions.cs +++ b/src/N.SourceGenerators.UnionTypes/Extensions/SyntaxNodeExtensions.cs @@ -9,6 +9,21 @@ public static bool IsTypeWithAttributes(this SyntaxNode s) AttributeLists.Count: > 0 }; } + + public static bool IsGenericTypeAttribute(this SyntaxNode s) + { + if (s is not TypeParameterSyntax typeParameter) + { + return false; + } + + if (typeParameter.Parent is not TypeParameterListSyntax typeParameterList) + { + return false; + } + + return typeParameterList.Parent is TypeDeclarationSyntax; + } public static bool IsPartial(this TypeDeclarationSyntax s) { diff --git a/src/N.SourceGenerators.UnionTypes/Models/UnionType.cs b/src/N.SourceGenerators.UnionTypes/Models/UnionType.cs index 605aace..10be2c8 100644 --- a/src/N.SourceGenerators.UnionTypes/Models/UnionType.cs +++ b/src/N.SourceGenerators.UnionTypes/Models/UnionType.cs @@ -40,9 +40,6 @@ public UnionType(INamedTypeSymbol containerType, IsPartial = syntax.IsPartial(); } - // TODO convert to simple model? - TypeArguments = containerType.TypeArguments; - IsReferenceType = containerType.IsReferenceType; IsValueType = containerType.IsValueType; HasToStringMethod = containerType.GetMembers().Any(IsToStringMethod); @@ -87,8 +84,6 @@ public UnionType(INamedTypeSymbol containerType, } } - public ImmutableArray TypeArguments { get; set; } - private static bool IsToStringMethod(ISymbol symbol) { return symbol is IMethodSymbol @@ -107,4 +102,43 @@ public Diagnostic CreateDiagnostic(DiagnosticDescriptor descriptor, params objec messageArgs ); } +} + +internal class UnionTypeComparer : IEqualityComparer +{ + public static UnionTypeComparer Instance { get; } = new(); + + private UnionTypeComparer() + { + } + + public bool Equals(UnionType x, UnionType y) + { + if (ReferenceEquals(x, y)) + { + return true; + } + + if (ReferenceEquals(x, null)) + { + return false; + } + + if (ReferenceEquals(y, null)) + { + return false; + } + + if (x.GetType() != y.GetType()) + { + return false; + } + + return x.TypeFullName == y.TypeFullName; + } + + public int GetHashCode(UnionType obj) + { + return obj.TypeFullName.GetHashCode(); + } } \ No newline at end of file diff --git a/src/N.SourceGenerators.UnionTypes/Models/UnionTypeVariant.cs b/src/N.SourceGenerators.UnionTypes/Models/UnionTypeVariant.cs index 109c279..d6a10f1 100644 --- a/src/N.SourceGenerators.UnionTypes/Models/UnionTypeVariant.cs +++ b/src/N.SourceGenerators.UnionTypes/Models/UnionTypeVariant.cs @@ -20,8 +20,9 @@ internal class UnionTypeVariant public bool IsValueType { get; } public int IdConstValue { get; internal set; } public bool IsInterface { get; } + public bool AllowNull { get; } - public UnionTypeVariant(ITypeSymbol typeSymbol, string? alias, int order) + public UnionTypeVariant(ITypeSymbol typeSymbol, string? alias, int order, bool allowNull) { Alias = alias ?? GetAlias(typeSymbol); Order = order; @@ -39,6 +40,7 @@ public UnionTypeVariant(ITypeSymbol typeSymbol, string? alias, int order) IdConstName = $"{Alias}Id"; IsValueType = typeSymbol.IsValueType; IsInterface = typeSymbol is { IsReferenceType: true, BaseType: null }; + AllowNull = allowNull; } private static HashSet GetKeywords() diff --git a/src/N.SourceGenerators.UnionTypes/N.SourceGenerators.UnionTypes.csproj b/src/N.SourceGenerators.UnionTypes/N.SourceGenerators.UnionTypes.csproj index 5e6bcb8..5115d33 100644 --- a/src/N.SourceGenerators.UnionTypes/N.SourceGenerators.UnionTypes.csproj +++ b/src/N.SourceGenerators.UnionTypes/N.SourceGenerators.UnionTypes.csproj @@ -10,7 +10,7 @@ true true ./nupkg - 0.24.0 + 0.25.3 true $(NoWarn);NU5128 diff --git a/src/N.SourceGenerators.UnionTypes/UnionTypesGenerator.Attributes.cs b/src/N.SourceGenerators.UnionTypes/UnionTypesGenerator.Attributes.cs index aa66a27..d224764 100644 --- a/src/N.SourceGenerators.UnionTypes/UnionTypesGenerator.Attributes.cs +++ b/src/N.SourceGenerators.UnionTypes/UnionTypesGenerator.Attributes.cs @@ -26,6 +26,7 @@ internal sealed class UnionTypeAttribute : Attribute public Type Type { get; } public string? Alias { get; } public int Order { get; } + public bool AllowNull { get; set; } public UnionTypeAttribute(Type type, string? alias = null, [CallerLineNumber] int order = 0) { @@ -45,9 +46,11 @@ public UnionTypeAttribute(Type type, string? alias = null, [CallerLineNumber] in namespace N.SourceGenerators.UnionTypes { - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] + [AttributeUsage(AttributeTargets.GenericParameter, Inherited = false, AllowMultiple = false)] internal sealed class GenericUnionTypeAttribute : Attribute { + public string? Alias { get; set; } + public bool AllowNull { get; set; } } } """; diff --git a/src/N.SourceGenerators.UnionTypes/UnionTypesGenerator.EqualityMembers.cs b/src/N.SourceGenerators.UnionTypes/UnionTypesGenerator.EqualityMembers.cs index 9ead064..0861329 100644 --- a/src/N.SourceGenerators.UnionTypes/UnionTypesGenerator.EqualityMembers.cs +++ b/src/N.SourceGenerators.UnionTypes/UnionTypesGenerator.EqualityMembers.cs @@ -14,10 +14,10 @@ private static MemberDeclarationSyntax GetHashCodeMethod(UnionType unionType) Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.OverrideKeyword) ).AddBodyStatements( - VariantsBodyStatements(unionType, v => AliasStatement(unionType, v)) + VariantsBodyStatements(unionType, AliasStatement) ); - static StatementSyntax AliasStatement(UnionType unionType, UnionTypeVariant variant) + static StatementSyntax AliasStatement(UnionTypeVariant variant) { return IfStatement( IsPropertyCondition(variant), @@ -110,10 +110,6 @@ IEnumerable BodyStatements() foreach (UnionTypeVariant variant in unionType.Variants) { MemberAccessExpressionSyntax memberAccess = MemberAccess("other", variant.FieldName); - if (variant.IsValueType && !unionType.UseStructLayout) - { - memberAccess = MemberAccess(memberAccess, "Value"); - } yield return IfStatement( IsPropertyCondition(variant), @@ -129,7 +125,7 @@ IEnumerable BodyStatements() IdentifierName("Equals") ) ).AddArgumentListArguments( - Argument(NotNullableArgumentExpression(unionType, variant)), + Argument(NotNullableArgumentExpression(variant)), Argument(memberAccess) ) ) diff --git a/src/N.SourceGenerators.UnionTypes/UnionTypesGenerator.cs b/src/N.SourceGenerators.UnionTypes/UnionTypesGenerator.cs index 317dae4..750ce84 100644 --- a/src/N.SourceGenerators.UnionTypes/UnionTypesGenerator.cs +++ b/src/N.SourceGenerators.UnionTypes/UnionTypesGenerator.cs @@ -1,4 +1,5 @@ -using System.Text; +using System.Collections.Immutable; +using System.Text; using N.SourceGenerators.UnionTypes.Extensions; using N.SourceGenerators.UnionTypes.Models; @@ -10,28 +11,52 @@ public sealed partial class UnionTypesGenerator : IIncrementalGenerator { private const string VariantIdFieldName = "_variantId"; - const string AutoGeneratedComment = """ - // - // This code was generated by https://github.com/Ne4to/N.SourceGenerators.UnionTypes - // Feel free to open an issue - // - """; + const string AutoGeneratedComment = +""" +// +// This code was generated by https://github.com/Ne4to/N.SourceGenerators.UnionTypes +// Feel free to open an issue +// +"""; public void Initialize(IncrementalGeneratorInitializationContext context) { AddAttributesSource(context); var unionTypes = GetUnionTypes(context); - var unionTypeDiagnostics = GetUnionTypeDiagnostics(unionTypes); - ProcessValues(context, unionTypeDiagnostics, GenerateUnionType); - var genericUnionTypes = GetGenericUnionTypes(context); - var genericUnionTypeDiagnostics = GetUnionTypeDiagnostics(genericUnionTypes); - ProcessValues(context, genericUnionTypeDiagnostics, GenerateUnionType); + + // TODO comparer does not work + var uniqueUnionTypes = unionTypes.WithComparer(UnionTypeComparer.Instance).Collect() + .Combine(genericUnionTypes.WithComparer(UnionTypeComparer.Instance).Collect()) + .SelectMany(ProcessCollections); + + var unionTypeDiagnostics = GetUnionTypeDiagnostics(uniqueUnionTypes); + ProcessValues(context, unionTypeDiagnostics, GenerateUnionType); GenerateConverters(context); } + private IEnumerable ProcessCollections((ImmutableArray Left, ImmutableArray Right) combination, CancellationToken arg2) + { + HashSet processedIds = new(); + foreach (UnionType unionType in combination.Left) + { + if (processedIds.Add(unionType.TypeFullName)) + { + yield return unionType; + } + } + + foreach (UnionType unionType in combination.Right) + { + if (processedIds.Add(unionType.TypeFullName)) + { + yield return unionType; + } + } + } + private static UnionType? GetUnionType(TypedConstant typedConstant) { var fromTypeSymbol = typedConstant.Value as INamedTypeSymbol; @@ -71,13 +96,16 @@ private static IncrementalValuesProvider GetGenericUnionTypes( return context.SyntaxProvider .ForAttributeWithMetadataName( GenericUnionTypeAttributeName, - static (s, _) => s.IsTypeWithAttributes(), + static (s, _) => s.IsGenericTypeAttribute(), static (context, ct) => { ct.ThrowIfCancellationRequested(); - TypeDeclarationSyntax typeDeclaration = (TypeDeclarationSyntax)context.TargetNode; - INamedTypeSymbol targetSymbol = (INamedTypeSymbol)context.TargetSymbol; + var typeParameter = (TypeParameterSyntax)context.TargetNode; + var typeParameterList = (TypeParameterListSyntax)typeParameter.Parent!; + + TypeDeclarationSyntax typeDeclaration = (TypeDeclarationSyntax)typeParameterList.Parent!; + INamedTypeSymbol targetSymbol = ((ITypeParameterSymbol)context.TargetSymbol).ContainingType; UnionType? unionType = GetUnionType(targetSymbol, typeDeclaration); return unionType; @@ -100,19 +128,39 @@ private static IncrementalValuesProvider GetGenericUnionTypes( var typeSymbol = attribute.ConstructorArguments[0].Value as ITypeSymbol; var alias = attribute.ConstructorArguments[1].Value?.ToString(); var order = (int)attribute.ConstructorArguments[2].Value!; + var allowNull = GetAllowNullValue(attribute); - variants.Add(new UnionTypeVariant(typeSymbol!, alias, order)); + variants.Add(new UnionTypeVariant(typeSymbol!, alias, order, allowNull)); } int typeArgumentIndex = -100; foreach (ITypeSymbol typeArgument in targetSymbol.TypeArguments) { - variants ??= new List(); - string alias = typeArgument.Name.StartsWith("T") && typeArgument.Name.Length > 1 - ? typeArgument.Name.Substring(1) - : typeArgument.Name; - variants.Add(new UnionTypeVariant(typeArgument, alias, typeArgumentIndex)); - typeArgumentIndex++; + foreach (AttributeData attribute in typeArgument.GetAttributes()) + { + if (attribute.AttributeClass?.ToDisplayString() != GenericUnionTypeAttributeName) + { + continue; + } + + variants ??= new List(); + var alias = attribute.NamedArguments + .Where(kvp => kvp.Key == "Alias") + .Select(kvp => (string?)kvp.Value.Value!) + .FirstOrDefault(); + + if (alias == null) + { + alias = typeArgument.Name.StartsWith("T") && typeArgument.Name.Length > 1 + ? typeArgument.Name.Substring(1) + : typeArgument.Name; + } + + var allowNull = GetAllowNullValue(attribute); + + variants.Add(new UnionTypeVariant(typeArgument, alias, typeArgumentIndex, allowNull)); + typeArgumentIndex++; + } } if (variants == null) @@ -128,6 +176,14 @@ private static IncrementalValuesProvider GetGenericUnionTypes( sortedVariants); return unionType; + + bool GetAllowNullValue(AttributeData attribute) + { + return attribute.NamedArguments + .Where(kvp => kvp.Key == "AllowNull") + .Select(kvp => (bool)kvp.Value.Value!) + .FirstOrDefault(); + } } static void GenerateUnionType(UnionType unionType, @@ -286,7 +342,7 @@ private static IEnumerable VariantMembers( yield return VariantConstant(variant); yield return Field(unionType, variant); yield return IsProperty(variant); - yield return AsPropertyWithStructLayout(unionType, variant); + yield return AsPropertyWithStructLayout(variant); yield return Ctor(unionType, variant); if (!variant.IsInterface) { @@ -296,7 +352,11 @@ private static IEnumerable VariantMembers( yield return TryGetMethod(variant); } - + + /// + /// private const int {Alias}Id = {IdConstValue}; + /// private const int SuccessId = 1; + /// private static MemberDeclarationSyntax VariantConstant(UnionTypeVariant variant) { return FieldDeclaration( @@ -318,8 +378,7 @@ private static MemberDeclarationSyntax VariantConstant(UnionTypeVariant variant) private static FieldDeclarationSyntax Field(UnionType unionType, UnionTypeVariant variant) { - TypeSyntax fieldType = IdentifierName(variant.TypeFullName) - .NullableTypeWhen(!unionType.UseStructLayout); + TypeSyntax fieldType = IdentifierName(variant.TypeFullName); var field = FieldDeclaration( VariableDeclaration(fieldType) @@ -359,24 +418,22 @@ private static BinaryExpressionSyntax IsPropertyCondition( IdentifierName(variant.IdConstName)); } - private static PropertyDeclarationSyntax AsPropertyWithStructLayout(UnionType unionType, UnionTypeVariant variant) + private static PropertyDeclarationSyntax AsPropertyWithStructLayout(UnionTypeVariant variant) { return PropertyDeclaration(IdentifierName(variant.TypeFullName), Identifier(variant.AsPropertyName)) .AddModifiers(Token(SyntaxKind.PublicKeyword)) .AddAccessorListAccessors( AccessorDeclaration(SyntaxKind.GetAccessorDeclaration) .AddBodyStatements( - AsPropertyWithStructLayoutBody(unionType, variant, null) + AsPropertyWithStructLayoutBody(variant, null) ) ); } - private static StatementSyntax[] AsPropertyWithStructLayoutBody( - UnionType unionType, - UnionTypeVariant variant, + private static StatementSyntax[] AsPropertyWithStructLayoutBody(UnionTypeVariant variant, string? memberName) { - ExpressionSyntax returnSyntax = NotNullableArgumentExpression(unionType, variant, memberName); + ExpressionSyntax returnSyntax = NotNullableArgumentExpression(variant, memberName); return new StatementSyntax[] { @@ -412,7 +469,7 @@ private static MemberDeclarationSyntax Ctor(UnionType unionType, UnionTypeVarian Parameter(Identifier(variant.ParameterName)) .WithType(IdentifierName(variant.TypeFullName)) ) - .AddBodyStatementsWhen(!unionType.UseStructLayout, ExpressionStatement(checkArgumentExpression)) + .AddBodyStatementsWhen(!unionType.UseStructLayout && !variant.AllowNull, ExpressionStatement(checkArgumentExpression)) .AddBodyStatements( ExpressionStatement(AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, @@ -465,13 +522,15 @@ private static MemberDeclarationSyntax ExplicitOperatorFromUnion(UnionType union .AddParameterListParameters(parameter); return operatorDeclaration - .AddBodyStatements(AsPropertyWithStructLayoutBody(unionType, variant, "value")); + .AddBodyStatements(AsPropertyWithStructLayoutBody(variant, "value")); } private static MemberDeclarationSyntax TryGetMethod(UnionTypeVariant variant) { - AttributeListSyntax attributeList = AttributeList() - .AddAttributes( + AttributeListSyntax attributeList = AttributeList(); + if (!variant.AllowNull) + { + attributeList = attributeList.AddAttributes( Attribute(IdentifierName("System.Diagnostics.CodeAnalysis.NotNullWhen"), AttributeArgumentList( SeparatedList( @@ -480,6 +539,7 @@ private static MemberDeclarationSyntax TryGetMethod(UnionTypeVariant variant) ) ) ); + } return MethodDeclaration( IdentifierName("bool"), @@ -490,9 +550,9 @@ private static MemberDeclarationSyntax TryGetMethod(UnionTypeVariant variant) ) .AddParameterListParameters( Parameter(Identifier("value")) - .WithType(NullableType(IdentifierName(variant.TypeFullName))) + .WithType(IdentifierName(variant.TypeFullName)) .AddModifiers(Token(SyntaxKind.OutKeyword)) - .AddAttributeLists(attributeList) + .AddAttributeListsWhen(attributeList.Attributes.Count > 0, attributeList) ).AddBodyStatements( IfStatement( IsPropertyCondition(variant), @@ -542,7 +602,7 @@ private static MemberDeclarationSyntax MatchMethod(UnionType unionType, bool isA .WithType(IdentifierName(CancellationTokenType)) ) .AddBodyStatements( - VariantsBodyStatements(unionType, v => MatchStatement(unionType, v, isAsync)) + VariantsBodyStatements(unionType, v => MatchStatement(v, isAsync)) ); } @@ -561,9 +621,9 @@ private static ParameterSyntax MatchMethodParameter(UnionTypeVariant variant, bo return parameter; } - private static StatementSyntax MatchStatement(UnionType unionType, UnionTypeVariant variant, bool isAsync) + private static StatementSyntax MatchStatement(UnionTypeVariant variant, bool isAsync) { - var argumentExpression = NotNullableArgumentExpression(unionType, variant); + var argumentExpression = NotNullableArgumentExpression(variant); return IfStatement( IsPropertyCondition(variant), @@ -578,23 +638,11 @@ private static StatementSyntax MatchStatement(UnionType unionType, UnionTypeVari ); } - private static ExpressionSyntax NotNullableArgumentExpression(UnionType unionType, UnionTypeVariant variant, string? memberName = null) + private static ExpressionSyntax NotNullableArgumentExpression(UnionTypeVariant variant, string? memberName = null) { return memberName == null - ? unionType.UseStructLayout - ? IdentifierName(variant.FieldName) - : variant.IsValueType - ? MemberAccess(variant.FieldName, "Value") - : PostfixUnaryExpression( - SyntaxKind.SuppressNullableWarningExpression, - IdentifierName(variant.FieldName)) - : unionType.UseStructLayout - ? MemberAccess(memberName, variant.FieldName) - : variant.IsValueType - ? MemberAccess(MemberAccess(memberName, variant.FieldName), "Value") - : PostfixUnaryExpression( - SyntaxKind.SuppressNullableWarningExpression, - MemberAccess(memberName, variant.FieldName)); + ? IdentifierName(variant.FieldName) + : MemberAccess(memberName, variant.FieldName); } private static MemberDeclarationSyntax SwitchMethod(UnionType unionType, bool isAsync) @@ -617,7 +665,7 @@ private static MemberDeclarationSyntax SwitchMethod(UnionType unionType, bool is .WithType(IdentifierName(CancellationTokenType)) ) .AddBodyStatements( - VariantsBodyStatements(unionType, v => SwitchStatement(unionType, v, isAsync)) + VariantsBodyStatements(unionType, v => SwitchStatement(v, isAsync)) ); } @@ -636,9 +684,9 @@ private static ParameterSyntax SwitchMethodParameter(UnionTypeVariant variant, b return parameter; } - private static StatementSyntax SwitchStatement(UnionType unionType, UnionTypeVariant variant, bool isAsync) + private static StatementSyntax SwitchStatement(UnionTypeVariant variant, bool isAsync) { - var argumentExpression = NotNullableArgumentExpression(unionType, variant); + var argumentExpression = NotNullableArgumentExpression(variant); return IfStatement( IsPropertyCondition(variant), diff --git a/tests/N.SourceGenerators.UnionTypes.BehaviorTests/ClassUnionTests.cs b/tests/N.SourceGenerators.UnionTypes.BehaviorTests/ClassUnionTests.cs index 82a5aef..82eac0a 100644 --- a/tests/N.SourceGenerators.UnionTypes.BehaviorTests/ClassUnionTests.cs +++ b/tests/N.SourceGenerators.UnionTypes.BehaviorTests/ClassUnionTests.cs @@ -48,13 +48,13 @@ public void AllOperations() // TryGet Assert.False(unionValue.TryGetValueNotSet(out var tryGetValueNotSetValue)); - Assert.Null(tryGetValueNotSetValue); + Assert.Equal(default, tryGetValueNotSetValue); Assert.True(unionValue.TryGetString(out var tryGetStringValue)); Assert.Equal("42", tryGetStringValue); Assert.False(unionValue.TryGetUserStatus(out var tryGetUserStatusValue)); - Assert.Null(tryGetUserStatusValue); + Assert.Equal(default, tryGetUserStatusValue); // Match var matchResult = unionValue.Match( diff --git a/tests/N.SourceGenerators.UnionTypes.BehaviorTests/GenericTests.cs b/tests/N.SourceGenerators.UnionTypes.BehaviorTests/GenericTests.cs index 07d38a0..3b275db 100644 --- a/tests/N.SourceGenerators.UnionTypes.BehaviorTests/GenericTests.cs +++ b/tests/N.SourceGenerators.UnionTypes.BehaviorTests/GenericTests.cs @@ -9,7 +9,7 @@ enum UserStatus } [UnionType(typeof(ValueNotSet))] -partial class GenericUnion +partial class GenericUnion<[GenericUnionType (Alias = "Result")] TValue> { } @@ -22,11 +22,11 @@ public void AllOperations() // IsProperty Assert.True(unionValue.IsValueNotSet); - Assert.False(unionValue.IsValue); + Assert.False(unionValue.IsResult); // AsProperty Assert.Equal(new ValueNotSet(), unionValue.AsValueNotSet); - Assert.Throws(() => _ = unionValue.AsValue); + Assert.Throws(() => _ = unionValue.AsResult); // .ctor GenericUnion ctorValueNotSet = new GenericUnion(new ValueNotSet()); @@ -44,22 +44,22 @@ public void AllOperations() Assert.Throws(() => _ = (UserStatus)unionValue); // TryGet - Assert.False(unionValue.TryGetValue(out var tryGetValue)); - Assert.Equal(default(UserStatus), tryGetValue); + Assert.False(unionValue.TryGetResult(out var tryGetResult)); + Assert.Equal(default(UserStatus), tryGetResult); Assert.True(unionValue.TryGetValueNotSet(out var tryGetValueNotSet)); Assert.Equal(new ValueNotSet(), tryGetValueNotSet); // Match var matchResult = unionValue.Match( - matchValue: _ => "Value", + matchResult: _ => "Result", matchValueNotSet: _ => "ValueNotSet"); Assert.Equal("ValueNotSet", matchResult); // Switch bool switchWasExecuted = false; unionValue.Switch( - switchValue: _ => Assert.Fail("switchValue should not be executed"), + switchResult: _ => Assert.Fail("switchResult should not be executed"), switchValueNotSet: x => { Assert.Equal(new ValueNotSet(), x); diff --git a/tests/N.SourceGenerators.UnionTypes.BehaviorTests/NullableValueTests.cs b/tests/N.SourceGenerators.UnionTypes.BehaviorTests/NullableValueTests.cs new file mode 100644 index 0000000..515f4d5 --- /dev/null +++ b/tests/N.SourceGenerators.UnionTypes.BehaviorTests/NullableValueTests.cs @@ -0,0 +1,54 @@ +using System.Runtime.CompilerServices; + +namespace N.SourceGenerators.UnionTypes.BehaviorTests; + +[UnionType(typeof(int?))] +[UnionType(typeof(string))] +public partial class ResultNotNullable +{ +} + +[UnionType(typeof(int?), AllowNull = true)] +[UnionType(typeof(string), AllowNull = true)] +public partial class ResultNullable +{ +} + +[UnionType(typeof(string), "Status", AllowNull = true)] +public partial class GenericResultNullable<[GenericUnionType(AllowNull = true, Alias = "Value")] T> +{ +} + +public class NullableValueTests +{ + [Fact] + public void NullValueNotAllowed() + { + Assert.Throws(() => new ResultNotNullable((int?)null)); + Assert.Throws(() => new ResultNotNullable((string)null)); + } + + [Fact] + public void NullValueAllowed() + { + var intResult = new ResultNullable((int?)null); + Assert.True(intResult.IsNullableOfInt32); + Assert.False(intResult.IsString); + + var stringResult = new ResultNullable((string)null); + Assert.True(stringResult.IsString); + Assert.False(stringResult.IsNullableOfInt32); + } + + [Fact] + public void GenericNullValueAllowed() + { + var intResult = new GenericResultNullable((int?)null); + Assert.True(intResult.IsValue); + Assert.False(intResult.IsStatus); + + var stringResult = new GenericResultNullable((string)null); + Assert.True(stringResult.IsStatus); + Assert.False(stringResult.IsValue); + } +} diff --git a/tests/N.SourceGenerators.UnionTypes.BehaviorTests/ReadonlyStructUnionTests.cs b/tests/N.SourceGenerators.UnionTypes.BehaviorTests/ReadonlyStructUnionTests.cs index 945cd11..f46970e 100644 --- a/tests/N.SourceGenerators.UnionTypes.BehaviorTests/ReadonlyStructUnionTests.cs +++ b/tests/N.SourceGenerators.UnionTypes.BehaviorTests/ReadonlyStructUnionTests.cs @@ -48,13 +48,13 @@ public void AllOperations() // TryGet Assert.False(unionValue.TryGetValueNotSet(out var tryGetValueNotSetValue)); - Assert.Null(tryGetValueNotSetValue); + Assert.Equal(default, tryGetValueNotSetValue); Assert.True(unionValue.TryGetString(out var tryGetStringValue)); Assert.Equal("42", tryGetStringValue); Assert.False(unionValue.TryGetUserStatus(out var tryGetUserStatusValue)); - Assert.Null(tryGetUserStatusValue); + Assert.Equal(default, tryGetUserStatusValue); // Match var matchResult = unionValue.Match( diff --git a/tests/N.SourceGenerators.UnionTypes.BehaviorTests/StructLayoutUnionTests.cs b/tests/N.SourceGenerators.UnionTypes.BehaviorTests/StructLayoutUnionTests.cs index 9a3b1c9..0915a97 100644 --- a/tests/N.SourceGenerators.UnionTypes.BehaviorTests/StructLayoutUnionTests.cs +++ b/tests/N.SourceGenerators.UnionTypes.BehaviorTests/StructLayoutUnionTests.cs @@ -49,10 +49,10 @@ public void AllOperations() // TryGet Assert.False(unionValue.TryGetValueNotSet(out var tryGetValueNotSetValue)); - Assert.Null(tryGetValueNotSetValue); + Assert.Equal(default, tryGetValueNotSetValue); Assert.False(unionValue.TryGetInt32(out var tryGetInt32Value)); - Assert.Null(tryGetInt32Value); + Assert.Equal(default, tryGetInt32Value); Assert.True(unionValue.TryGetUserStatus(out var tryGetUserStatusValue)); Assert.Equal(UserStatus.Active, tryGetUserStatusValue); diff --git a/tests/N.SourceGenerators.UnionTypes.BehaviorTests/StructUnionTests.cs b/tests/N.SourceGenerators.UnionTypes.BehaviorTests/StructUnionTests.cs index 6a9f6e3..d8deaa4 100644 --- a/tests/N.SourceGenerators.UnionTypes.BehaviorTests/StructUnionTests.cs +++ b/tests/N.SourceGenerators.UnionTypes.BehaviorTests/StructUnionTests.cs @@ -48,13 +48,13 @@ public void AllOperations() // TryGet Assert.False(unionValue.TryGetValueNotSet(out var tryGetValueNotSetValue)); - Assert.Null(tryGetValueNotSetValue); + Assert.Equal(default, tryGetValueNotSetValue); Assert.True(unionValue.TryGetString(out var tryGetStringValue)); Assert.Equal("42", tryGetStringValue); Assert.False(unionValue.TryGetUserStatus(out var tryGetUserStatusValue)); - Assert.Null(tryGetUserStatusValue); + Assert.Equal(default, tryGetUserStatusValue); // Match var matchResult = unionValue.Match( diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/GenericUnionTests.cs b/tests/N.SourceGenerators.UnionTypes.Tests/GenericUnionTests.cs index 17c2bee..1daa52d 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/GenericUnionTests.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/GenericUnionTests.cs @@ -10,8 +10,7 @@ public Task OnlyGenericTypes() using System; using N.SourceGenerators.UnionTypes; -[GenericUnionType] -public partial class OperationDataResult +public partial class OperationDataResult<[GenericUnionType(Alias = "Result")] T, [GenericUnionType] TError> { } """; @@ -27,7 +26,23 @@ public Task WithCustomUnionType() using N.SourceGenerators.UnionTypes; [UnionType(typeof(int))] -public partial class OperationDataResult +public partial class OperationDataResult<[GenericUnionType] TResult, [GenericUnionType] TError> +{ +} +"""; + + return TestHelper.Verify(source); + } + + [Fact] + public Task WithAlias() + { + const string source = """ +using System; +using N.SourceGenerators.UnionTypes; + +[UnionType(typeof(string), "Status", AllowNull = true)] +public partial class GenericResultNullable<[GenericUnionType(AllowNull = true, Alias = "Value")] T> { } """; diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/NullableValueTests.cs b/tests/N.SourceGenerators.UnionTypes.Tests/NullableValueTests.cs new file mode 100644 index 0000000..0727edd --- /dev/null +++ b/tests/N.SourceGenerators.UnionTypes.Tests/NullableValueTests.cs @@ -0,0 +1,24 @@ +namespace N.SourceGenerators.UnionTypes.Tests; + +[UsesVerify] +public class NullableValueTests +{ + [Fact] + public Task UseAllowNullAttribute() + { + const string source = +""" +using System; +using System.Collections.Generic; +using N.SourceGenerators.UnionTypes; + +[UnionType(typeof(int?), AllowNull = true)] +[UnionType(typeof(string))] +public partial class Result +{ +} +"""; + + return TestHelper.Verify(source); + } +} \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ExternalConverter#BusinessLogicResult.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ExternalConverter#BusinessLogicResult.g.verified.cs index 4ea6dee..aeb4efc 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ExternalConverter#BusinessLogicResult.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ExternalConverter#BusinessLogicResult.g.verified.cs @@ -11,14 +11,14 @@ partial class BusinessLogicResult : System.IEquatable { private readonly int _variantId; private const int SuccessId = 1; - private readonly global::MyApp.Success? _success; + private readonly global::MyApp.Success _success; public bool IsSuccess => _variantId == SuccessId; public global::MyApp.Success AsSuccess { get { if (_variantId == SuccessId) - return _success!; + return _success; throw new System.InvalidOperationException("Inner value is not Success"); } } @@ -34,11 +34,11 @@ public BusinessLogicResult(global::MyApp.Success success) public static explicit operator global::MyApp.Success(BusinessLogicResult value) { if (value._variantId == SuccessId) - return value._success!; + return value._success; throw new System.InvalidOperationException("Inner value is not Success"); } - public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success? value) + public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success value) { if (_variantId == SuccessId) { @@ -53,14 +53,14 @@ public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] ou } private const int NotFoundErrorId = 2; - private readonly global::MyApp.NotFoundError? _notFoundError; + private readonly global::MyApp.NotFoundError _notFoundError; public bool IsNotFoundError => _variantId == NotFoundErrorId; public global::MyApp.NotFoundError AsNotFoundError { get { if (_variantId == NotFoundErrorId) - return _notFoundError!; + return _notFoundError; throw new System.InvalidOperationException("Inner value is not NotFoundError"); } } @@ -76,11 +76,11 @@ public BusinessLogicResult(global::MyApp.NotFoundError notFoundError) public static explicit operator global::MyApp.NotFoundError(BusinessLogicResult value) { if (value._variantId == NotFoundErrorId) - return value._notFoundError!; + return value._notFoundError; throw new System.InvalidOperationException("Inner value is not NotFoundError"); } - public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.NotFoundError? value) + public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.NotFoundError value) { if (_variantId == NotFoundErrorId) { @@ -95,14 +95,14 @@ public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(tru } private const int ValidationErrorId = 3; - private readonly global::MyApp.ValidationError? _validationError; + private readonly global::MyApp.ValidationError _validationError; public bool IsValidationError => _variantId == ValidationErrorId; public global::MyApp.ValidationError AsValidationError { get { if (_variantId == ValidationErrorId) - return _validationError!; + return _validationError; throw new System.InvalidOperationException("Inner value is not ValidationError"); } } @@ -118,11 +118,11 @@ public BusinessLogicResult(global::MyApp.ValidationError validationError) public static explicit operator global::MyApp.ValidationError(BusinessLogicResult value) { if (value._variantId == ValidationErrorId) - return value._validationError!; + return value._validationError; throw new System.InvalidOperationException("Inner value is not ValidationError"); } - public bool TryGetValidationError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.ValidationError? value) + public bool TryGetValidationError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.ValidationError value) { if (_variantId == ValidationErrorId) { @@ -139,22 +139,22 @@ public bool TryGetValidationError([System.Diagnostics.CodeAnalysis.NotNullWhen(t public TOut Match(global::System.Func matchSuccess, global::System.Func matchNotFoundError, global::System.Func matchValidationError) { if (_variantId == SuccessId) - return matchSuccess(_success!); + return matchSuccess(_success); if (_variantId == NotFoundErrorId) - return matchNotFoundError(_notFoundError!); + return matchNotFoundError(_notFoundError); if (_variantId == ValidationErrorId) - return matchValidationError(_validationError!); + return matchValidationError(_validationError); throw new System.InvalidOperationException("Inner type is unknown"); } public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchSuccess, global::System.Func> matchNotFoundError, global::System.Func> matchValidationError, global::System.Threading.CancellationToken ct) { if (_variantId == SuccessId) - return await matchSuccess(_success!, ct).ConfigureAwait(false); + return await matchSuccess(_success, ct).ConfigureAwait(false); if (_variantId == NotFoundErrorId) - return await matchNotFoundError(_notFoundError!, ct).ConfigureAwait(false); + return await matchNotFoundError(_notFoundError, ct).ConfigureAwait(false); if (_variantId == ValidationErrorId) - return await matchValidationError(_validationError!, ct).ConfigureAwait(false); + return await matchValidationError(_validationError, ct).ConfigureAwait(false); throw new System.InvalidOperationException("Inner type is unknown"); } @@ -162,19 +162,19 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - switchSuccess(_success!); + switchSuccess(_success); return; } if (_variantId == NotFoundErrorId) { - switchNotFoundError(_notFoundError!); + switchNotFoundError(_notFoundError); return; } if (_variantId == ValidationErrorId) { - switchValidationError(_validationError!); + switchValidationError(_validationError); return; } @@ -185,19 +185,19 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - await switchSuccess(_success!, ct).ConfigureAwait(false); + await switchSuccess(_success, ct).ConfigureAwait(false); return; } if (_variantId == NotFoundErrorId) { - await switchNotFoundError(_notFoundError!, ct).ConfigureAwait(false); + await switchNotFoundError(_notFoundError, ct).ConfigureAwait(false); return; } if (_variantId == ValidationErrorId) { - await switchValidationError(_validationError!, ct).ConfigureAwait(false); + await switchValidationError(_validationError, ct).ConfigureAwait(false); return; } @@ -257,11 +257,11 @@ public bool Equals(BusinessLogicResult? other) } if (_variantId == SuccessId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_success!, other._success); + return System.Collections.Generic.EqualityComparer.Default.Equals(_success, other._success); if (_variantId == NotFoundErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_notFoundError!, other._notFoundError); + return System.Collections.Generic.EqualityComparer.Default.Equals(_notFoundError, other._notFoundError); if (_variantId == ValidationErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_validationError!, other._validationError); + return System.Collections.Generic.EqualityComparer.Default.Equals(_validationError, other._validationError); throw new System.InvalidOperationException("Inner type is unknown"); } diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ExternalConverter#DataAccessResult.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ExternalConverter#DataAccessResult.g.verified.cs index 3fbfac7..d8df1e4 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ExternalConverter#DataAccessResult.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ExternalConverter#DataAccessResult.g.verified.cs @@ -11,14 +11,14 @@ partial class DataAccessResult : System.IEquatable { private readonly int _variantId; private const int SuccessId = 1; - private readonly global::MyApp.Success? _success; + private readonly global::MyApp.Success _success; public bool IsSuccess => _variantId == SuccessId; public global::MyApp.Success AsSuccess { get { if (_variantId == SuccessId) - return _success!; + return _success; throw new System.InvalidOperationException("Inner value is not Success"); } } @@ -34,11 +34,11 @@ public DataAccessResult(global::MyApp.Success success) public static explicit operator global::MyApp.Success(DataAccessResult value) { if (value._variantId == SuccessId) - return value._success!; + return value._success; throw new System.InvalidOperationException("Inner value is not Success"); } - public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success? value) + public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success value) { if (_variantId == SuccessId) { @@ -53,14 +53,14 @@ public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] ou } private const int NotFoundErrorId = 2; - private readonly global::MyApp.NotFoundError? _notFoundError; + private readonly global::MyApp.NotFoundError _notFoundError; public bool IsNotFoundError => _variantId == NotFoundErrorId; public global::MyApp.NotFoundError AsNotFoundError { get { if (_variantId == NotFoundErrorId) - return _notFoundError!; + return _notFoundError; throw new System.InvalidOperationException("Inner value is not NotFoundError"); } } @@ -76,11 +76,11 @@ public DataAccessResult(global::MyApp.NotFoundError notFoundError) public static explicit operator global::MyApp.NotFoundError(DataAccessResult value) { if (value._variantId == NotFoundErrorId) - return value._notFoundError!; + return value._notFoundError; throw new System.InvalidOperationException("Inner value is not NotFoundError"); } - public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.NotFoundError? value) + public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.NotFoundError value) { if (_variantId == NotFoundErrorId) { @@ -97,18 +97,18 @@ public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(tru public TOut Match(global::System.Func matchSuccess, global::System.Func matchNotFoundError) { if (_variantId == SuccessId) - return matchSuccess(_success!); + return matchSuccess(_success); if (_variantId == NotFoundErrorId) - return matchNotFoundError(_notFoundError!); + return matchNotFoundError(_notFoundError); throw new System.InvalidOperationException("Inner type is unknown"); } public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchSuccess, global::System.Func> matchNotFoundError, global::System.Threading.CancellationToken ct) { if (_variantId == SuccessId) - return await matchSuccess(_success!, ct).ConfigureAwait(false); + return await matchSuccess(_success, ct).ConfigureAwait(false); if (_variantId == NotFoundErrorId) - return await matchNotFoundError(_notFoundError!, ct).ConfigureAwait(false); + return await matchNotFoundError(_notFoundError, ct).ConfigureAwait(false); throw new System.InvalidOperationException("Inner type is unknown"); } @@ -116,13 +116,13 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - switchSuccess(_success!); + switchSuccess(_success); return; } if (_variantId == NotFoundErrorId) { - switchNotFoundError(_notFoundError!); + switchNotFoundError(_notFoundError); return; } @@ -133,13 +133,13 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - await switchSuccess(_success!, ct).ConfigureAwait(false); + await switchSuccess(_success, ct).ConfigureAwait(false); return; } if (_variantId == NotFoundErrorId) { - await switchNotFoundError(_notFoundError!, ct).ConfigureAwait(false); + await switchNotFoundError(_notFoundError, ct).ConfigureAwait(false); return; } @@ -195,9 +195,9 @@ public bool Equals(DataAccessResult? other) } if (_variantId == SuccessId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_success!, other._success); + return System.Collections.Generic.EqualityComparer.Default.Equals(_success, other._success); if (_variantId == NotFoundErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_notFoundError!, other._notFoundError); + return System.Collections.Generic.EqualityComparer.Default.Equals(_notFoundError, other._notFoundError); throw new System.InvalidOperationException("Inner type is unknown"); } diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ExternalConverter#GenericUnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ExternalConverter#GenericUnionTypeAttribute.g.verified.cs index 853ee82..e256764 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ExternalConverter#GenericUnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ExternalConverter#GenericUnionTypeAttribute.g.verified.cs @@ -9,8 +9,10 @@ namespace N.SourceGenerators.UnionTypes { - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] + [AttributeUsage(AttributeTargets.GenericParameter, Inherited = false, AllowMultiple = false)] internal sealed class GenericUnionTypeAttribute : Attribute { + public string? Alias { get; set; } + public bool AllowNull { get; set; } } } \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ExternalConverter#UnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ExternalConverter#UnionTypeAttribute.g.verified.cs index c9f95c1..c8f7fed 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ExternalConverter#UnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ExternalConverter#UnionTypeAttribute.g.verified.cs @@ -15,6 +15,7 @@ internal sealed class UnionTypeAttribute : Attribute public Type Type { get; } public string? Alias { get; } public int Order { get; } + public bool AllowNull { get; set; } public UnionTypeAttribute(Type type, string? alias = null, [CallerLineNumber] int order = 0) { diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ExternalConverterReportsDiagnostic#BusinessLogicResult.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ExternalConverterReportsDiagnostic#BusinessLogicResult.g.verified.cs index 8108740..401dc51 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ExternalConverterReportsDiagnostic#BusinessLogicResult.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ExternalConverterReportsDiagnostic#BusinessLogicResult.g.verified.cs @@ -11,14 +11,14 @@ partial class BusinessLogicResult : System.IEquatable { private readonly int _variantId; private const int SuccessId = 1; - private readonly global::MyApp.Success? _success; + private readonly global::MyApp.Success _success; public bool IsSuccess => _variantId == SuccessId; public global::MyApp.Success AsSuccess { get { if (_variantId == SuccessId) - return _success!; + return _success; throw new System.InvalidOperationException("Inner value is not Success"); } } @@ -34,11 +34,11 @@ public BusinessLogicResult(global::MyApp.Success success) public static explicit operator global::MyApp.Success(BusinessLogicResult value) { if (value._variantId == SuccessId) - return value._success!; + return value._success; throw new System.InvalidOperationException("Inner value is not Success"); } - public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success? value) + public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success value) { if (_variantId == SuccessId) { @@ -53,14 +53,14 @@ public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] ou } private const int ValidationErrorId = 2; - private readonly global::MyApp.ValidationError? _validationError; + private readonly global::MyApp.ValidationError _validationError; public bool IsValidationError => _variantId == ValidationErrorId; public global::MyApp.ValidationError AsValidationError { get { if (_variantId == ValidationErrorId) - return _validationError!; + return _validationError; throw new System.InvalidOperationException("Inner value is not ValidationError"); } } @@ -76,11 +76,11 @@ public BusinessLogicResult(global::MyApp.ValidationError validationError) public static explicit operator global::MyApp.ValidationError(BusinessLogicResult value) { if (value._variantId == ValidationErrorId) - return value._validationError!; + return value._validationError; throw new System.InvalidOperationException("Inner value is not ValidationError"); } - public bool TryGetValidationError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.ValidationError? value) + public bool TryGetValidationError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.ValidationError value) { if (_variantId == ValidationErrorId) { @@ -97,18 +97,18 @@ public bool TryGetValidationError([System.Diagnostics.CodeAnalysis.NotNullWhen(t public TOut Match(global::System.Func matchSuccess, global::System.Func matchValidationError) { if (_variantId == SuccessId) - return matchSuccess(_success!); + return matchSuccess(_success); if (_variantId == ValidationErrorId) - return matchValidationError(_validationError!); + return matchValidationError(_validationError); throw new System.InvalidOperationException("Inner type is unknown"); } public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchSuccess, global::System.Func> matchValidationError, global::System.Threading.CancellationToken ct) { if (_variantId == SuccessId) - return await matchSuccess(_success!, ct).ConfigureAwait(false); + return await matchSuccess(_success, ct).ConfigureAwait(false); if (_variantId == ValidationErrorId) - return await matchValidationError(_validationError!, ct).ConfigureAwait(false); + return await matchValidationError(_validationError, ct).ConfigureAwait(false); throw new System.InvalidOperationException("Inner type is unknown"); } @@ -116,13 +116,13 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - switchSuccess(_success!); + switchSuccess(_success); return; } if (_variantId == ValidationErrorId) { - switchValidationError(_validationError!); + switchValidationError(_validationError); return; } @@ -133,13 +133,13 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - await switchSuccess(_success!, ct).ConfigureAwait(false); + await switchSuccess(_success, ct).ConfigureAwait(false); return; } if (_variantId == ValidationErrorId) { - await switchValidationError(_validationError!, ct).ConfigureAwait(false); + await switchValidationError(_validationError, ct).ConfigureAwait(false); return; } @@ -195,9 +195,9 @@ public bool Equals(BusinessLogicResult? other) } if (_variantId == SuccessId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_success!, other._success); + return System.Collections.Generic.EqualityComparer.Default.Equals(_success, other._success); if (_variantId == ValidationErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_validationError!, other._validationError); + return System.Collections.Generic.EqualityComparer.Default.Equals(_validationError, other._validationError); throw new System.InvalidOperationException("Inner type is unknown"); } diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ExternalConverterReportsDiagnostic#DataAccessResult.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ExternalConverterReportsDiagnostic#DataAccessResult.g.verified.cs index 3fbfac7..d8df1e4 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ExternalConverterReportsDiagnostic#DataAccessResult.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ExternalConverterReportsDiagnostic#DataAccessResult.g.verified.cs @@ -11,14 +11,14 @@ partial class DataAccessResult : System.IEquatable { private readonly int _variantId; private const int SuccessId = 1; - private readonly global::MyApp.Success? _success; + private readonly global::MyApp.Success _success; public bool IsSuccess => _variantId == SuccessId; public global::MyApp.Success AsSuccess { get { if (_variantId == SuccessId) - return _success!; + return _success; throw new System.InvalidOperationException("Inner value is not Success"); } } @@ -34,11 +34,11 @@ public DataAccessResult(global::MyApp.Success success) public static explicit operator global::MyApp.Success(DataAccessResult value) { if (value._variantId == SuccessId) - return value._success!; + return value._success; throw new System.InvalidOperationException("Inner value is not Success"); } - public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success? value) + public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success value) { if (_variantId == SuccessId) { @@ -53,14 +53,14 @@ public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] ou } private const int NotFoundErrorId = 2; - private readonly global::MyApp.NotFoundError? _notFoundError; + private readonly global::MyApp.NotFoundError _notFoundError; public bool IsNotFoundError => _variantId == NotFoundErrorId; public global::MyApp.NotFoundError AsNotFoundError { get { if (_variantId == NotFoundErrorId) - return _notFoundError!; + return _notFoundError; throw new System.InvalidOperationException("Inner value is not NotFoundError"); } } @@ -76,11 +76,11 @@ public DataAccessResult(global::MyApp.NotFoundError notFoundError) public static explicit operator global::MyApp.NotFoundError(DataAccessResult value) { if (value._variantId == NotFoundErrorId) - return value._notFoundError!; + return value._notFoundError; throw new System.InvalidOperationException("Inner value is not NotFoundError"); } - public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.NotFoundError? value) + public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.NotFoundError value) { if (_variantId == NotFoundErrorId) { @@ -97,18 +97,18 @@ public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(tru public TOut Match(global::System.Func matchSuccess, global::System.Func matchNotFoundError) { if (_variantId == SuccessId) - return matchSuccess(_success!); + return matchSuccess(_success); if (_variantId == NotFoundErrorId) - return matchNotFoundError(_notFoundError!); + return matchNotFoundError(_notFoundError); throw new System.InvalidOperationException("Inner type is unknown"); } public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchSuccess, global::System.Func> matchNotFoundError, global::System.Threading.CancellationToken ct) { if (_variantId == SuccessId) - return await matchSuccess(_success!, ct).ConfigureAwait(false); + return await matchSuccess(_success, ct).ConfigureAwait(false); if (_variantId == NotFoundErrorId) - return await matchNotFoundError(_notFoundError!, ct).ConfigureAwait(false); + return await matchNotFoundError(_notFoundError, ct).ConfigureAwait(false); throw new System.InvalidOperationException("Inner type is unknown"); } @@ -116,13 +116,13 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - switchSuccess(_success!); + switchSuccess(_success); return; } if (_variantId == NotFoundErrorId) { - switchNotFoundError(_notFoundError!); + switchNotFoundError(_notFoundError); return; } @@ -133,13 +133,13 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - await switchSuccess(_success!, ct).ConfigureAwait(false); + await switchSuccess(_success, ct).ConfigureAwait(false); return; } if (_variantId == NotFoundErrorId) { - await switchNotFoundError(_notFoundError!, ct).ConfigureAwait(false); + await switchNotFoundError(_notFoundError, ct).ConfigureAwait(false); return; } @@ -195,9 +195,9 @@ public bool Equals(DataAccessResult? other) } if (_variantId == SuccessId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_success!, other._success); + return System.Collections.Generic.EqualityComparer.Default.Equals(_success, other._success); if (_variantId == NotFoundErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_notFoundError!, other._notFoundError); + return System.Collections.Generic.EqualityComparer.Default.Equals(_notFoundError, other._notFoundError); throw new System.InvalidOperationException("Inner type is unknown"); } diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ExternalConverterReportsDiagnostic#GenericUnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ExternalConverterReportsDiagnostic#GenericUnionTypeAttribute.g.verified.cs index 853ee82..e256764 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ExternalConverterReportsDiagnostic#GenericUnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ExternalConverterReportsDiagnostic#GenericUnionTypeAttribute.g.verified.cs @@ -9,8 +9,10 @@ namespace N.SourceGenerators.UnionTypes { - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] + [AttributeUsage(AttributeTargets.GenericParameter, Inherited = false, AllowMultiple = false)] internal sealed class GenericUnionTypeAttribute : Attribute { + public string? Alias { get; set; } + public bool AllowNull { get; set; } } } \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ExternalConverterReportsDiagnostic#UnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ExternalConverterReportsDiagnostic#UnionTypeAttribute.g.verified.cs index c9f95c1..c8f7fed 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ExternalConverterReportsDiagnostic#UnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ExternalConverterReportsDiagnostic#UnionTypeAttribute.g.verified.cs @@ -15,6 +15,7 @@ internal sealed class UnionTypeAttribute : Attribute public Type Type { get; } public string? Alias { get; } public int Order { get; } + public bool AllowNull { get; set; } public UnionTypeAttribute(Type type, string? alias = null, [CallerLineNumber] int order = 0) { diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.FromConverter#BusinessLogicResult.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.FromConverter#BusinessLogicResult.g.verified.cs index 4ea6dee..aeb4efc 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.FromConverter#BusinessLogicResult.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.FromConverter#BusinessLogicResult.g.verified.cs @@ -11,14 +11,14 @@ partial class BusinessLogicResult : System.IEquatable { private readonly int _variantId; private const int SuccessId = 1; - private readonly global::MyApp.Success? _success; + private readonly global::MyApp.Success _success; public bool IsSuccess => _variantId == SuccessId; public global::MyApp.Success AsSuccess { get { if (_variantId == SuccessId) - return _success!; + return _success; throw new System.InvalidOperationException("Inner value is not Success"); } } @@ -34,11 +34,11 @@ public BusinessLogicResult(global::MyApp.Success success) public static explicit operator global::MyApp.Success(BusinessLogicResult value) { if (value._variantId == SuccessId) - return value._success!; + return value._success; throw new System.InvalidOperationException("Inner value is not Success"); } - public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success? value) + public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success value) { if (_variantId == SuccessId) { @@ -53,14 +53,14 @@ public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] ou } private const int NotFoundErrorId = 2; - private readonly global::MyApp.NotFoundError? _notFoundError; + private readonly global::MyApp.NotFoundError _notFoundError; public bool IsNotFoundError => _variantId == NotFoundErrorId; public global::MyApp.NotFoundError AsNotFoundError { get { if (_variantId == NotFoundErrorId) - return _notFoundError!; + return _notFoundError; throw new System.InvalidOperationException("Inner value is not NotFoundError"); } } @@ -76,11 +76,11 @@ public BusinessLogicResult(global::MyApp.NotFoundError notFoundError) public static explicit operator global::MyApp.NotFoundError(BusinessLogicResult value) { if (value._variantId == NotFoundErrorId) - return value._notFoundError!; + return value._notFoundError; throw new System.InvalidOperationException("Inner value is not NotFoundError"); } - public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.NotFoundError? value) + public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.NotFoundError value) { if (_variantId == NotFoundErrorId) { @@ -95,14 +95,14 @@ public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(tru } private const int ValidationErrorId = 3; - private readonly global::MyApp.ValidationError? _validationError; + private readonly global::MyApp.ValidationError _validationError; public bool IsValidationError => _variantId == ValidationErrorId; public global::MyApp.ValidationError AsValidationError { get { if (_variantId == ValidationErrorId) - return _validationError!; + return _validationError; throw new System.InvalidOperationException("Inner value is not ValidationError"); } } @@ -118,11 +118,11 @@ public BusinessLogicResult(global::MyApp.ValidationError validationError) public static explicit operator global::MyApp.ValidationError(BusinessLogicResult value) { if (value._variantId == ValidationErrorId) - return value._validationError!; + return value._validationError; throw new System.InvalidOperationException("Inner value is not ValidationError"); } - public bool TryGetValidationError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.ValidationError? value) + public bool TryGetValidationError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.ValidationError value) { if (_variantId == ValidationErrorId) { @@ -139,22 +139,22 @@ public bool TryGetValidationError([System.Diagnostics.CodeAnalysis.NotNullWhen(t public TOut Match(global::System.Func matchSuccess, global::System.Func matchNotFoundError, global::System.Func matchValidationError) { if (_variantId == SuccessId) - return matchSuccess(_success!); + return matchSuccess(_success); if (_variantId == NotFoundErrorId) - return matchNotFoundError(_notFoundError!); + return matchNotFoundError(_notFoundError); if (_variantId == ValidationErrorId) - return matchValidationError(_validationError!); + return matchValidationError(_validationError); throw new System.InvalidOperationException("Inner type is unknown"); } public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchSuccess, global::System.Func> matchNotFoundError, global::System.Func> matchValidationError, global::System.Threading.CancellationToken ct) { if (_variantId == SuccessId) - return await matchSuccess(_success!, ct).ConfigureAwait(false); + return await matchSuccess(_success, ct).ConfigureAwait(false); if (_variantId == NotFoundErrorId) - return await matchNotFoundError(_notFoundError!, ct).ConfigureAwait(false); + return await matchNotFoundError(_notFoundError, ct).ConfigureAwait(false); if (_variantId == ValidationErrorId) - return await matchValidationError(_validationError!, ct).ConfigureAwait(false); + return await matchValidationError(_validationError, ct).ConfigureAwait(false); throw new System.InvalidOperationException("Inner type is unknown"); } @@ -162,19 +162,19 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - switchSuccess(_success!); + switchSuccess(_success); return; } if (_variantId == NotFoundErrorId) { - switchNotFoundError(_notFoundError!); + switchNotFoundError(_notFoundError); return; } if (_variantId == ValidationErrorId) { - switchValidationError(_validationError!); + switchValidationError(_validationError); return; } @@ -185,19 +185,19 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - await switchSuccess(_success!, ct).ConfigureAwait(false); + await switchSuccess(_success, ct).ConfigureAwait(false); return; } if (_variantId == NotFoundErrorId) { - await switchNotFoundError(_notFoundError!, ct).ConfigureAwait(false); + await switchNotFoundError(_notFoundError, ct).ConfigureAwait(false); return; } if (_variantId == ValidationErrorId) { - await switchValidationError(_validationError!, ct).ConfigureAwait(false); + await switchValidationError(_validationError, ct).ConfigureAwait(false); return; } @@ -257,11 +257,11 @@ public bool Equals(BusinessLogicResult? other) } if (_variantId == SuccessId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_success!, other._success); + return System.Collections.Generic.EqualityComparer.Default.Equals(_success, other._success); if (_variantId == NotFoundErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_notFoundError!, other._notFoundError); + return System.Collections.Generic.EqualityComparer.Default.Equals(_notFoundError, other._notFoundError); if (_variantId == ValidationErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_validationError!, other._validationError); + return System.Collections.Generic.EqualityComparer.Default.Equals(_validationError, other._validationError); throw new System.InvalidOperationException("Inner type is unknown"); } diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.FromConverter#DataAccessResult.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.FromConverter#DataAccessResult.g.verified.cs index 3fbfac7..d8df1e4 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.FromConverter#DataAccessResult.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.FromConverter#DataAccessResult.g.verified.cs @@ -11,14 +11,14 @@ partial class DataAccessResult : System.IEquatable { private readonly int _variantId; private const int SuccessId = 1; - private readonly global::MyApp.Success? _success; + private readonly global::MyApp.Success _success; public bool IsSuccess => _variantId == SuccessId; public global::MyApp.Success AsSuccess { get { if (_variantId == SuccessId) - return _success!; + return _success; throw new System.InvalidOperationException("Inner value is not Success"); } } @@ -34,11 +34,11 @@ public DataAccessResult(global::MyApp.Success success) public static explicit operator global::MyApp.Success(DataAccessResult value) { if (value._variantId == SuccessId) - return value._success!; + return value._success; throw new System.InvalidOperationException("Inner value is not Success"); } - public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success? value) + public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success value) { if (_variantId == SuccessId) { @@ -53,14 +53,14 @@ public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] ou } private const int NotFoundErrorId = 2; - private readonly global::MyApp.NotFoundError? _notFoundError; + private readonly global::MyApp.NotFoundError _notFoundError; public bool IsNotFoundError => _variantId == NotFoundErrorId; public global::MyApp.NotFoundError AsNotFoundError { get { if (_variantId == NotFoundErrorId) - return _notFoundError!; + return _notFoundError; throw new System.InvalidOperationException("Inner value is not NotFoundError"); } } @@ -76,11 +76,11 @@ public DataAccessResult(global::MyApp.NotFoundError notFoundError) public static explicit operator global::MyApp.NotFoundError(DataAccessResult value) { if (value._variantId == NotFoundErrorId) - return value._notFoundError!; + return value._notFoundError; throw new System.InvalidOperationException("Inner value is not NotFoundError"); } - public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.NotFoundError? value) + public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.NotFoundError value) { if (_variantId == NotFoundErrorId) { @@ -97,18 +97,18 @@ public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(tru public TOut Match(global::System.Func matchSuccess, global::System.Func matchNotFoundError) { if (_variantId == SuccessId) - return matchSuccess(_success!); + return matchSuccess(_success); if (_variantId == NotFoundErrorId) - return matchNotFoundError(_notFoundError!); + return matchNotFoundError(_notFoundError); throw new System.InvalidOperationException("Inner type is unknown"); } public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchSuccess, global::System.Func> matchNotFoundError, global::System.Threading.CancellationToken ct) { if (_variantId == SuccessId) - return await matchSuccess(_success!, ct).ConfigureAwait(false); + return await matchSuccess(_success, ct).ConfigureAwait(false); if (_variantId == NotFoundErrorId) - return await matchNotFoundError(_notFoundError!, ct).ConfigureAwait(false); + return await matchNotFoundError(_notFoundError, ct).ConfigureAwait(false); throw new System.InvalidOperationException("Inner type is unknown"); } @@ -116,13 +116,13 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - switchSuccess(_success!); + switchSuccess(_success); return; } if (_variantId == NotFoundErrorId) { - switchNotFoundError(_notFoundError!); + switchNotFoundError(_notFoundError); return; } @@ -133,13 +133,13 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - await switchSuccess(_success!, ct).ConfigureAwait(false); + await switchSuccess(_success, ct).ConfigureAwait(false); return; } if (_variantId == NotFoundErrorId) { - await switchNotFoundError(_notFoundError!, ct).ConfigureAwait(false); + await switchNotFoundError(_notFoundError, ct).ConfigureAwait(false); return; } @@ -195,9 +195,9 @@ public bool Equals(DataAccessResult? other) } if (_variantId == SuccessId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_success!, other._success); + return System.Collections.Generic.EqualityComparer.Default.Equals(_success, other._success); if (_variantId == NotFoundErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_notFoundError!, other._notFoundError); + return System.Collections.Generic.EqualityComparer.Default.Equals(_notFoundError, other._notFoundError); throw new System.InvalidOperationException("Inner type is unknown"); } diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.FromConverter#GenericUnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.FromConverter#GenericUnionTypeAttribute.g.verified.cs index 853ee82..e256764 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.FromConverter#GenericUnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.FromConverter#GenericUnionTypeAttribute.g.verified.cs @@ -9,8 +9,10 @@ namespace N.SourceGenerators.UnionTypes { - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] + [AttributeUsage(AttributeTargets.GenericParameter, Inherited = false, AllowMultiple = false)] internal sealed class GenericUnionTypeAttribute : Attribute { + public string? Alias { get; set; } + public bool AllowNull { get; set; } } } \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.FromConverter#UnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.FromConverter#UnionTypeAttribute.g.verified.cs index c9f95c1..c8f7fed 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.FromConverter#UnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.FromConverter#UnionTypeAttribute.g.verified.cs @@ -15,6 +15,7 @@ internal sealed class UnionTypeAttribute : Attribute public Type Type { get; } public string? Alias { get; } public int Order { get; } + public bool AllowNull { get; set; } public UnionTypeAttribute(Type type, string? alias = null, [CallerLineNumber] int order = 0) { diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.FromConverterReportsDiagnostic#BusinessLogicResult.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.FromConverterReportsDiagnostic#BusinessLogicResult.g.verified.cs index 8108740..401dc51 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.FromConverterReportsDiagnostic#BusinessLogicResult.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.FromConverterReportsDiagnostic#BusinessLogicResult.g.verified.cs @@ -11,14 +11,14 @@ partial class BusinessLogicResult : System.IEquatable { private readonly int _variantId; private const int SuccessId = 1; - private readonly global::MyApp.Success? _success; + private readonly global::MyApp.Success _success; public bool IsSuccess => _variantId == SuccessId; public global::MyApp.Success AsSuccess { get { if (_variantId == SuccessId) - return _success!; + return _success; throw new System.InvalidOperationException("Inner value is not Success"); } } @@ -34,11 +34,11 @@ public BusinessLogicResult(global::MyApp.Success success) public static explicit operator global::MyApp.Success(BusinessLogicResult value) { if (value._variantId == SuccessId) - return value._success!; + return value._success; throw new System.InvalidOperationException("Inner value is not Success"); } - public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success? value) + public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success value) { if (_variantId == SuccessId) { @@ -53,14 +53,14 @@ public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] ou } private const int ValidationErrorId = 2; - private readonly global::MyApp.ValidationError? _validationError; + private readonly global::MyApp.ValidationError _validationError; public bool IsValidationError => _variantId == ValidationErrorId; public global::MyApp.ValidationError AsValidationError { get { if (_variantId == ValidationErrorId) - return _validationError!; + return _validationError; throw new System.InvalidOperationException("Inner value is not ValidationError"); } } @@ -76,11 +76,11 @@ public BusinessLogicResult(global::MyApp.ValidationError validationError) public static explicit operator global::MyApp.ValidationError(BusinessLogicResult value) { if (value._variantId == ValidationErrorId) - return value._validationError!; + return value._validationError; throw new System.InvalidOperationException("Inner value is not ValidationError"); } - public bool TryGetValidationError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.ValidationError? value) + public bool TryGetValidationError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.ValidationError value) { if (_variantId == ValidationErrorId) { @@ -97,18 +97,18 @@ public bool TryGetValidationError([System.Diagnostics.CodeAnalysis.NotNullWhen(t public TOut Match(global::System.Func matchSuccess, global::System.Func matchValidationError) { if (_variantId == SuccessId) - return matchSuccess(_success!); + return matchSuccess(_success); if (_variantId == ValidationErrorId) - return matchValidationError(_validationError!); + return matchValidationError(_validationError); throw new System.InvalidOperationException("Inner type is unknown"); } public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchSuccess, global::System.Func> matchValidationError, global::System.Threading.CancellationToken ct) { if (_variantId == SuccessId) - return await matchSuccess(_success!, ct).ConfigureAwait(false); + return await matchSuccess(_success, ct).ConfigureAwait(false); if (_variantId == ValidationErrorId) - return await matchValidationError(_validationError!, ct).ConfigureAwait(false); + return await matchValidationError(_validationError, ct).ConfigureAwait(false); throw new System.InvalidOperationException("Inner type is unknown"); } @@ -116,13 +116,13 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - switchSuccess(_success!); + switchSuccess(_success); return; } if (_variantId == ValidationErrorId) { - switchValidationError(_validationError!); + switchValidationError(_validationError); return; } @@ -133,13 +133,13 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - await switchSuccess(_success!, ct).ConfigureAwait(false); + await switchSuccess(_success, ct).ConfigureAwait(false); return; } if (_variantId == ValidationErrorId) { - await switchValidationError(_validationError!, ct).ConfigureAwait(false); + await switchValidationError(_validationError, ct).ConfigureAwait(false); return; } @@ -195,9 +195,9 @@ public bool Equals(BusinessLogicResult? other) } if (_variantId == SuccessId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_success!, other._success); + return System.Collections.Generic.EqualityComparer.Default.Equals(_success, other._success); if (_variantId == ValidationErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_validationError!, other._validationError); + return System.Collections.Generic.EqualityComparer.Default.Equals(_validationError, other._validationError); throw new System.InvalidOperationException("Inner type is unknown"); } diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.FromConverterReportsDiagnostic#DataAccessResult.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.FromConverterReportsDiagnostic#DataAccessResult.g.verified.cs index 3fbfac7..d8df1e4 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.FromConverterReportsDiagnostic#DataAccessResult.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.FromConverterReportsDiagnostic#DataAccessResult.g.verified.cs @@ -11,14 +11,14 @@ partial class DataAccessResult : System.IEquatable { private readonly int _variantId; private const int SuccessId = 1; - private readonly global::MyApp.Success? _success; + private readonly global::MyApp.Success _success; public bool IsSuccess => _variantId == SuccessId; public global::MyApp.Success AsSuccess { get { if (_variantId == SuccessId) - return _success!; + return _success; throw new System.InvalidOperationException("Inner value is not Success"); } } @@ -34,11 +34,11 @@ public DataAccessResult(global::MyApp.Success success) public static explicit operator global::MyApp.Success(DataAccessResult value) { if (value._variantId == SuccessId) - return value._success!; + return value._success; throw new System.InvalidOperationException("Inner value is not Success"); } - public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success? value) + public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success value) { if (_variantId == SuccessId) { @@ -53,14 +53,14 @@ public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] ou } private const int NotFoundErrorId = 2; - private readonly global::MyApp.NotFoundError? _notFoundError; + private readonly global::MyApp.NotFoundError _notFoundError; public bool IsNotFoundError => _variantId == NotFoundErrorId; public global::MyApp.NotFoundError AsNotFoundError { get { if (_variantId == NotFoundErrorId) - return _notFoundError!; + return _notFoundError; throw new System.InvalidOperationException("Inner value is not NotFoundError"); } } @@ -76,11 +76,11 @@ public DataAccessResult(global::MyApp.NotFoundError notFoundError) public static explicit operator global::MyApp.NotFoundError(DataAccessResult value) { if (value._variantId == NotFoundErrorId) - return value._notFoundError!; + return value._notFoundError; throw new System.InvalidOperationException("Inner value is not NotFoundError"); } - public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.NotFoundError? value) + public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.NotFoundError value) { if (_variantId == NotFoundErrorId) { @@ -97,18 +97,18 @@ public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(tru public TOut Match(global::System.Func matchSuccess, global::System.Func matchNotFoundError) { if (_variantId == SuccessId) - return matchSuccess(_success!); + return matchSuccess(_success); if (_variantId == NotFoundErrorId) - return matchNotFoundError(_notFoundError!); + return matchNotFoundError(_notFoundError); throw new System.InvalidOperationException("Inner type is unknown"); } public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchSuccess, global::System.Func> matchNotFoundError, global::System.Threading.CancellationToken ct) { if (_variantId == SuccessId) - return await matchSuccess(_success!, ct).ConfigureAwait(false); + return await matchSuccess(_success, ct).ConfigureAwait(false); if (_variantId == NotFoundErrorId) - return await matchNotFoundError(_notFoundError!, ct).ConfigureAwait(false); + return await matchNotFoundError(_notFoundError, ct).ConfigureAwait(false); throw new System.InvalidOperationException("Inner type is unknown"); } @@ -116,13 +116,13 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - switchSuccess(_success!); + switchSuccess(_success); return; } if (_variantId == NotFoundErrorId) { - switchNotFoundError(_notFoundError!); + switchNotFoundError(_notFoundError); return; } @@ -133,13 +133,13 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - await switchSuccess(_success!, ct).ConfigureAwait(false); + await switchSuccess(_success, ct).ConfigureAwait(false); return; } if (_variantId == NotFoundErrorId) { - await switchNotFoundError(_notFoundError!, ct).ConfigureAwait(false); + await switchNotFoundError(_notFoundError, ct).ConfigureAwait(false); return; } @@ -195,9 +195,9 @@ public bool Equals(DataAccessResult? other) } if (_variantId == SuccessId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_success!, other._success); + return System.Collections.Generic.EqualityComparer.Default.Equals(_success, other._success); if (_variantId == NotFoundErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_notFoundError!, other._notFoundError); + return System.Collections.Generic.EqualityComparer.Default.Equals(_notFoundError, other._notFoundError); throw new System.InvalidOperationException("Inner type is unknown"); } diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.FromConverterReportsDiagnostic#GenericUnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.FromConverterReportsDiagnostic#GenericUnionTypeAttribute.g.verified.cs index 853ee82..e256764 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.FromConverterReportsDiagnostic#GenericUnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.FromConverterReportsDiagnostic#GenericUnionTypeAttribute.g.verified.cs @@ -9,8 +9,10 @@ namespace N.SourceGenerators.UnionTypes { - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] + [AttributeUsage(AttributeTargets.GenericParameter, Inherited = false, AllowMultiple = false)] internal sealed class GenericUnionTypeAttribute : Attribute { + public string? Alias { get; set; } + public bool AllowNull { get; set; } } } \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.FromConverterReportsDiagnostic#UnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.FromConverterReportsDiagnostic#UnionTypeAttribute.g.verified.cs index c9f95c1..c8f7fed 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.FromConverterReportsDiagnostic#UnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.FromConverterReportsDiagnostic#UnionTypeAttribute.g.verified.cs @@ -15,6 +15,7 @@ internal sealed class UnionTypeAttribute : Attribute public Type Type { get; } public string? Alias { get; } public int Order { get; } + public bool AllowNull { get; set; } public UnionTypeAttribute(Type type, string? alias = null, [CallerLineNumber] int order = 0) { diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.StaticExternalConverter#BusinessLogicResult.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.StaticExternalConverter#BusinessLogicResult.g.verified.cs index 4ea6dee..aeb4efc 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.StaticExternalConverter#BusinessLogicResult.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.StaticExternalConverter#BusinessLogicResult.g.verified.cs @@ -11,14 +11,14 @@ partial class BusinessLogicResult : System.IEquatable { private readonly int _variantId; private const int SuccessId = 1; - private readonly global::MyApp.Success? _success; + private readonly global::MyApp.Success _success; public bool IsSuccess => _variantId == SuccessId; public global::MyApp.Success AsSuccess { get { if (_variantId == SuccessId) - return _success!; + return _success; throw new System.InvalidOperationException("Inner value is not Success"); } } @@ -34,11 +34,11 @@ public BusinessLogicResult(global::MyApp.Success success) public static explicit operator global::MyApp.Success(BusinessLogicResult value) { if (value._variantId == SuccessId) - return value._success!; + return value._success; throw new System.InvalidOperationException("Inner value is not Success"); } - public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success? value) + public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success value) { if (_variantId == SuccessId) { @@ -53,14 +53,14 @@ public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] ou } private const int NotFoundErrorId = 2; - private readonly global::MyApp.NotFoundError? _notFoundError; + private readonly global::MyApp.NotFoundError _notFoundError; public bool IsNotFoundError => _variantId == NotFoundErrorId; public global::MyApp.NotFoundError AsNotFoundError { get { if (_variantId == NotFoundErrorId) - return _notFoundError!; + return _notFoundError; throw new System.InvalidOperationException("Inner value is not NotFoundError"); } } @@ -76,11 +76,11 @@ public BusinessLogicResult(global::MyApp.NotFoundError notFoundError) public static explicit operator global::MyApp.NotFoundError(BusinessLogicResult value) { if (value._variantId == NotFoundErrorId) - return value._notFoundError!; + return value._notFoundError; throw new System.InvalidOperationException("Inner value is not NotFoundError"); } - public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.NotFoundError? value) + public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.NotFoundError value) { if (_variantId == NotFoundErrorId) { @@ -95,14 +95,14 @@ public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(tru } private const int ValidationErrorId = 3; - private readonly global::MyApp.ValidationError? _validationError; + private readonly global::MyApp.ValidationError _validationError; public bool IsValidationError => _variantId == ValidationErrorId; public global::MyApp.ValidationError AsValidationError { get { if (_variantId == ValidationErrorId) - return _validationError!; + return _validationError; throw new System.InvalidOperationException("Inner value is not ValidationError"); } } @@ -118,11 +118,11 @@ public BusinessLogicResult(global::MyApp.ValidationError validationError) public static explicit operator global::MyApp.ValidationError(BusinessLogicResult value) { if (value._variantId == ValidationErrorId) - return value._validationError!; + return value._validationError; throw new System.InvalidOperationException("Inner value is not ValidationError"); } - public bool TryGetValidationError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.ValidationError? value) + public bool TryGetValidationError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.ValidationError value) { if (_variantId == ValidationErrorId) { @@ -139,22 +139,22 @@ public bool TryGetValidationError([System.Diagnostics.CodeAnalysis.NotNullWhen(t public TOut Match(global::System.Func matchSuccess, global::System.Func matchNotFoundError, global::System.Func matchValidationError) { if (_variantId == SuccessId) - return matchSuccess(_success!); + return matchSuccess(_success); if (_variantId == NotFoundErrorId) - return matchNotFoundError(_notFoundError!); + return matchNotFoundError(_notFoundError); if (_variantId == ValidationErrorId) - return matchValidationError(_validationError!); + return matchValidationError(_validationError); throw new System.InvalidOperationException("Inner type is unknown"); } public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchSuccess, global::System.Func> matchNotFoundError, global::System.Func> matchValidationError, global::System.Threading.CancellationToken ct) { if (_variantId == SuccessId) - return await matchSuccess(_success!, ct).ConfigureAwait(false); + return await matchSuccess(_success, ct).ConfigureAwait(false); if (_variantId == NotFoundErrorId) - return await matchNotFoundError(_notFoundError!, ct).ConfigureAwait(false); + return await matchNotFoundError(_notFoundError, ct).ConfigureAwait(false); if (_variantId == ValidationErrorId) - return await matchValidationError(_validationError!, ct).ConfigureAwait(false); + return await matchValidationError(_validationError, ct).ConfigureAwait(false); throw new System.InvalidOperationException("Inner type is unknown"); } @@ -162,19 +162,19 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - switchSuccess(_success!); + switchSuccess(_success); return; } if (_variantId == NotFoundErrorId) { - switchNotFoundError(_notFoundError!); + switchNotFoundError(_notFoundError); return; } if (_variantId == ValidationErrorId) { - switchValidationError(_validationError!); + switchValidationError(_validationError); return; } @@ -185,19 +185,19 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - await switchSuccess(_success!, ct).ConfigureAwait(false); + await switchSuccess(_success, ct).ConfigureAwait(false); return; } if (_variantId == NotFoundErrorId) { - await switchNotFoundError(_notFoundError!, ct).ConfigureAwait(false); + await switchNotFoundError(_notFoundError, ct).ConfigureAwait(false); return; } if (_variantId == ValidationErrorId) { - await switchValidationError(_validationError!, ct).ConfigureAwait(false); + await switchValidationError(_validationError, ct).ConfigureAwait(false); return; } @@ -257,11 +257,11 @@ public bool Equals(BusinessLogicResult? other) } if (_variantId == SuccessId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_success!, other._success); + return System.Collections.Generic.EqualityComparer.Default.Equals(_success, other._success); if (_variantId == NotFoundErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_notFoundError!, other._notFoundError); + return System.Collections.Generic.EqualityComparer.Default.Equals(_notFoundError, other._notFoundError); if (_variantId == ValidationErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_validationError!, other._validationError); + return System.Collections.Generic.EqualityComparer.Default.Equals(_validationError, other._validationError); throw new System.InvalidOperationException("Inner type is unknown"); } diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.StaticExternalConverter#DataAccessResult.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.StaticExternalConverter#DataAccessResult.g.verified.cs index 3fbfac7..d8df1e4 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.StaticExternalConverter#DataAccessResult.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.StaticExternalConverter#DataAccessResult.g.verified.cs @@ -11,14 +11,14 @@ partial class DataAccessResult : System.IEquatable { private readonly int _variantId; private const int SuccessId = 1; - private readonly global::MyApp.Success? _success; + private readonly global::MyApp.Success _success; public bool IsSuccess => _variantId == SuccessId; public global::MyApp.Success AsSuccess { get { if (_variantId == SuccessId) - return _success!; + return _success; throw new System.InvalidOperationException("Inner value is not Success"); } } @@ -34,11 +34,11 @@ public DataAccessResult(global::MyApp.Success success) public static explicit operator global::MyApp.Success(DataAccessResult value) { if (value._variantId == SuccessId) - return value._success!; + return value._success; throw new System.InvalidOperationException("Inner value is not Success"); } - public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success? value) + public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success value) { if (_variantId == SuccessId) { @@ -53,14 +53,14 @@ public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] ou } private const int NotFoundErrorId = 2; - private readonly global::MyApp.NotFoundError? _notFoundError; + private readonly global::MyApp.NotFoundError _notFoundError; public bool IsNotFoundError => _variantId == NotFoundErrorId; public global::MyApp.NotFoundError AsNotFoundError { get { if (_variantId == NotFoundErrorId) - return _notFoundError!; + return _notFoundError; throw new System.InvalidOperationException("Inner value is not NotFoundError"); } } @@ -76,11 +76,11 @@ public DataAccessResult(global::MyApp.NotFoundError notFoundError) public static explicit operator global::MyApp.NotFoundError(DataAccessResult value) { if (value._variantId == NotFoundErrorId) - return value._notFoundError!; + return value._notFoundError; throw new System.InvalidOperationException("Inner value is not NotFoundError"); } - public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.NotFoundError? value) + public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.NotFoundError value) { if (_variantId == NotFoundErrorId) { @@ -97,18 +97,18 @@ public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(tru public TOut Match(global::System.Func matchSuccess, global::System.Func matchNotFoundError) { if (_variantId == SuccessId) - return matchSuccess(_success!); + return matchSuccess(_success); if (_variantId == NotFoundErrorId) - return matchNotFoundError(_notFoundError!); + return matchNotFoundError(_notFoundError); throw new System.InvalidOperationException("Inner type is unknown"); } public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchSuccess, global::System.Func> matchNotFoundError, global::System.Threading.CancellationToken ct) { if (_variantId == SuccessId) - return await matchSuccess(_success!, ct).ConfigureAwait(false); + return await matchSuccess(_success, ct).ConfigureAwait(false); if (_variantId == NotFoundErrorId) - return await matchNotFoundError(_notFoundError!, ct).ConfigureAwait(false); + return await matchNotFoundError(_notFoundError, ct).ConfigureAwait(false); throw new System.InvalidOperationException("Inner type is unknown"); } @@ -116,13 +116,13 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - switchSuccess(_success!); + switchSuccess(_success); return; } if (_variantId == NotFoundErrorId) { - switchNotFoundError(_notFoundError!); + switchNotFoundError(_notFoundError); return; } @@ -133,13 +133,13 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - await switchSuccess(_success!, ct).ConfigureAwait(false); + await switchSuccess(_success, ct).ConfigureAwait(false); return; } if (_variantId == NotFoundErrorId) { - await switchNotFoundError(_notFoundError!, ct).ConfigureAwait(false); + await switchNotFoundError(_notFoundError, ct).ConfigureAwait(false); return; } @@ -195,9 +195,9 @@ public bool Equals(DataAccessResult? other) } if (_variantId == SuccessId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_success!, other._success); + return System.Collections.Generic.EqualityComparer.Default.Equals(_success, other._success); if (_variantId == NotFoundErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_notFoundError!, other._notFoundError); + return System.Collections.Generic.EqualityComparer.Default.Equals(_notFoundError, other._notFoundError); throw new System.InvalidOperationException("Inner type is unknown"); } diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.StaticExternalConverter#GenericUnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.StaticExternalConverter#GenericUnionTypeAttribute.g.verified.cs index 853ee82..e256764 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.StaticExternalConverter#GenericUnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.StaticExternalConverter#GenericUnionTypeAttribute.g.verified.cs @@ -9,8 +9,10 @@ namespace N.SourceGenerators.UnionTypes { - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] + [AttributeUsage(AttributeTargets.GenericParameter, Inherited = false, AllowMultiple = false)] internal sealed class GenericUnionTypeAttribute : Attribute { + public string? Alias { get; set; } + public bool AllowNull { get; set; } } } \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.StaticExternalConverter#UnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.StaticExternalConverter#UnionTypeAttribute.g.verified.cs index c9f95c1..c8f7fed 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.StaticExternalConverter#UnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.StaticExternalConverter#UnionTypeAttribute.g.verified.cs @@ -15,6 +15,7 @@ internal sealed class UnionTypeAttribute : Attribute public Type Type { get; } public string? Alias { get; } public int Order { get; } + public bool AllowNull { get; set; } public UnionTypeAttribute(Type type, string? alias = null, [CallerLineNumber] int order = 0) { diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.StaticExternalConverterReportsDiagnostic#BusinessLogicResult.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.StaticExternalConverterReportsDiagnostic#BusinessLogicResult.g.verified.cs index 8108740..401dc51 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.StaticExternalConverterReportsDiagnostic#BusinessLogicResult.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.StaticExternalConverterReportsDiagnostic#BusinessLogicResult.g.verified.cs @@ -11,14 +11,14 @@ partial class BusinessLogicResult : System.IEquatable { private readonly int _variantId; private const int SuccessId = 1; - private readonly global::MyApp.Success? _success; + private readonly global::MyApp.Success _success; public bool IsSuccess => _variantId == SuccessId; public global::MyApp.Success AsSuccess { get { if (_variantId == SuccessId) - return _success!; + return _success; throw new System.InvalidOperationException("Inner value is not Success"); } } @@ -34,11 +34,11 @@ public BusinessLogicResult(global::MyApp.Success success) public static explicit operator global::MyApp.Success(BusinessLogicResult value) { if (value._variantId == SuccessId) - return value._success!; + return value._success; throw new System.InvalidOperationException("Inner value is not Success"); } - public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success? value) + public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success value) { if (_variantId == SuccessId) { @@ -53,14 +53,14 @@ public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] ou } private const int ValidationErrorId = 2; - private readonly global::MyApp.ValidationError? _validationError; + private readonly global::MyApp.ValidationError _validationError; public bool IsValidationError => _variantId == ValidationErrorId; public global::MyApp.ValidationError AsValidationError { get { if (_variantId == ValidationErrorId) - return _validationError!; + return _validationError; throw new System.InvalidOperationException("Inner value is not ValidationError"); } } @@ -76,11 +76,11 @@ public BusinessLogicResult(global::MyApp.ValidationError validationError) public static explicit operator global::MyApp.ValidationError(BusinessLogicResult value) { if (value._variantId == ValidationErrorId) - return value._validationError!; + return value._validationError; throw new System.InvalidOperationException("Inner value is not ValidationError"); } - public bool TryGetValidationError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.ValidationError? value) + public bool TryGetValidationError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.ValidationError value) { if (_variantId == ValidationErrorId) { @@ -97,18 +97,18 @@ public bool TryGetValidationError([System.Diagnostics.CodeAnalysis.NotNullWhen(t public TOut Match(global::System.Func matchSuccess, global::System.Func matchValidationError) { if (_variantId == SuccessId) - return matchSuccess(_success!); + return matchSuccess(_success); if (_variantId == ValidationErrorId) - return matchValidationError(_validationError!); + return matchValidationError(_validationError); throw new System.InvalidOperationException("Inner type is unknown"); } public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchSuccess, global::System.Func> matchValidationError, global::System.Threading.CancellationToken ct) { if (_variantId == SuccessId) - return await matchSuccess(_success!, ct).ConfigureAwait(false); + return await matchSuccess(_success, ct).ConfigureAwait(false); if (_variantId == ValidationErrorId) - return await matchValidationError(_validationError!, ct).ConfigureAwait(false); + return await matchValidationError(_validationError, ct).ConfigureAwait(false); throw new System.InvalidOperationException("Inner type is unknown"); } @@ -116,13 +116,13 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - switchSuccess(_success!); + switchSuccess(_success); return; } if (_variantId == ValidationErrorId) { - switchValidationError(_validationError!); + switchValidationError(_validationError); return; } @@ -133,13 +133,13 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - await switchSuccess(_success!, ct).ConfigureAwait(false); + await switchSuccess(_success, ct).ConfigureAwait(false); return; } if (_variantId == ValidationErrorId) { - await switchValidationError(_validationError!, ct).ConfigureAwait(false); + await switchValidationError(_validationError, ct).ConfigureAwait(false); return; } @@ -195,9 +195,9 @@ public bool Equals(BusinessLogicResult? other) } if (_variantId == SuccessId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_success!, other._success); + return System.Collections.Generic.EqualityComparer.Default.Equals(_success, other._success); if (_variantId == ValidationErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_validationError!, other._validationError); + return System.Collections.Generic.EqualityComparer.Default.Equals(_validationError, other._validationError); throw new System.InvalidOperationException("Inner type is unknown"); } diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.StaticExternalConverterReportsDiagnostic#DataAccessResult.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.StaticExternalConverterReportsDiagnostic#DataAccessResult.g.verified.cs index 3fbfac7..d8df1e4 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.StaticExternalConverterReportsDiagnostic#DataAccessResult.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.StaticExternalConverterReportsDiagnostic#DataAccessResult.g.verified.cs @@ -11,14 +11,14 @@ partial class DataAccessResult : System.IEquatable { private readonly int _variantId; private const int SuccessId = 1; - private readonly global::MyApp.Success? _success; + private readonly global::MyApp.Success _success; public bool IsSuccess => _variantId == SuccessId; public global::MyApp.Success AsSuccess { get { if (_variantId == SuccessId) - return _success!; + return _success; throw new System.InvalidOperationException("Inner value is not Success"); } } @@ -34,11 +34,11 @@ public DataAccessResult(global::MyApp.Success success) public static explicit operator global::MyApp.Success(DataAccessResult value) { if (value._variantId == SuccessId) - return value._success!; + return value._success; throw new System.InvalidOperationException("Inner value is not Success"); } - public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success? value) + public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success value) { if (_variantId == SuccessId) { @@ -53,14 +53,14 @@ public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] ou } private const int NotFoundErrorId = 2; - private readonly global::MyApp.NotFoundError? _notFoundError; + private readonly global::MyApp.NotFoundError _notFoundError; public bool IsNotFoundError => _variantId == NotFoundErrorId; public global::MyApp.NotFoundError AsNotFoundError { get { if (_variantId == NotFoundErrorId) - return _notFoundError!; + return _notFoundError; throw new System.InvalidOperationException("Inner value is not NotFoundError"); } } @@ -76,11 +76,11 @@ public DataAccessResult(global::MyApp.NotFoundError notFoundError) public static explicit operator global::MyApp.NotFoundError(DataAccessResult value) { if (value._variantId == NotFoundErrorId) - return value._notFoundError!; + return value._notFoundError; throw new System.InvalidOperationException("Inner value is not NotFoundError"); } - public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.NotFoundError? value) + public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.NotFoundError value) { if (_variantId == NotFoundErrorId) { @@ -97,18 +97,18 @@ public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(tru public TOut Match(global::System.Func matchSuccess, global::System.Func matchNotFoundError) { if (_variantId == SuccessId) - return matchSuccess(_success!); + return matchSuccess(_success); if (_variantId == NotFoundErrorId) - return matchNotFoundError(_notFoundError!); + return matchNotFoundError(_notFoundError); throw new System.InvalidOperationException("Inner type is unknown"); } public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchSuccess, global::System.Func> matchNotFoundError, global::System.Threading.CancellationToken ct) { if (_variantId == SuccessId) - return await matchSuccess(_success!, ct).ConfigureAwait(false); + return await matchSuccess(_success, ct).ConfigureAwait(false); if (_variantId == NotFoundErrorId) - return await matchNotFoundError(_notFoundError!, ct).ConfigureAwait(false); + return await matchNotFoundError(_notFoundError, ct).ConfigureAwait(false); throw new System.InvalidOperationException("Inner type is unknown"); } @@ -116,13 +116,13 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - switchSuccess(_success!); + switchSuccess(_success); return; } if (_variantId == NotFoundErrorId) { - switchNotFoundError(_notFoundError!); + switchNotFoundError(_notFoundError); return; } @@ -133,13 +133,13 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - await switchSuccess(_success!, ct).ConfigureAwait(false); + await switchSuccess(_success, ct).ConfigureAwait(false); return; } if (_variantId == NotFoundErrorId) { - await switchNotFoundError(_notFoundError!, ct).ConfigureAwait(false); + await switchNotFoundError(_notFoundError, ct).ConfigureAwait(false); return; } @@ -195,9 +195,9 @@ public bool Equals(DataAccessResult? other) } if (_variantId == SuccessId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_success!, other._success); + return System.Collections.Generic.EqualityComparer.Default.Equals(_success, other._success); if (_variantId == NotFoundErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_notFoundError!, other._notFoundError); + return System.Collections.Generic.EqualityComparer.Default.Equals(_notFoundError, other._notFoundError); throw new System.InvalidOperationException("Inner type is unknown"); } diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.StaticExternalConverterReportsDiagnostic#GenericUnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.StaticExternalConverterReportsDiagnostic#GenericUnionTypeAttribute.g.verified.cs index 853ee82..e256764 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.StaticExternalConverterReportsDiagnostic#GenericUnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.StaticExternalConverterReportsDiagnostic#GenericUnionTypeAttribute.g.verified.cs @@ -9,8 +9,10 @@ namespace N.SourceGenerators.UnionTypes { - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] + [AttributeUsage(AttributeTargets.GenericParameter, Inherited = false, AllowMultiple = false)] internal sealed class GenericUnionTypeAttribute : Attribute { + public string? Alias { get; set; } + public bool AllowNull { get; set; } } } \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.StaticExternalConverterReportsDiagnostic#UnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.StaticExternalConverterReportsDiagnostic#UnionTypeAttribute.g.verified.cs index c9f95c1..c8f7fed 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.StaticExternalConverterReportsDiagnostic#UnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.StaticExternalConverterReportsDiagnostic#UnionTypeAttribute.g.verified.cs @@ -15,6 +15,7 @@ internal sealed class UnionTypeAttribute : Attribute public Type Type { get; } public string? Alias { get; } public int Order { get; } + public bool AllowNull { get; set; } public UnionTypeAttribute(Type type, string? alias = null, [CallerLineNumber] int order = 0) { diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ToConverter#BusinessLogicResult.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ToConverter#BusinessLogicResult.g.verified.cs index 4ea6dee..aeb4efc 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ToConverter#BusinessLogicResult.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ToConverter#BusinessLogicResult.g.verified.cs @@ -11,14 +11,14 @@ partial class BusinessLogicResult : System.IEquatable { private readonly int _variantId; private const int SuccessId = 1; - private readonly global::MyApp.Success? _success; + private readonly global::MyApp.Success _success; public bool IsSuccess => _variantId == SuccessId; public global::MyApp.Success AsSuccess { get { if (_variantId == SuccessId) - return _success!; + return _success; throw new System.InvalidOperationException("Inner value is not Success"); } } @@ -34,11 +34,11 @@ public BusinessLogicResult(global::MyApp.Success success) public static explicit operator global::MyApp.Success(BusinessLogicResult value) { if (value._variantId == SuccessId) - return value._success!; + return value._success; throw new System.InvalidOperationException("Inner value is not Success"); } - public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success? value) + public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success value) { if (_variantId == SuccessId) { @@ -53,14 +53,14 @@ public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] ou } private const int NotFoundErrorId = 2; - private readonly global::MyApp.NotFoundError? _notFoundError; + private readonly global::MyApp.NotFoundError _notFoundError; public bool IsNotFoundError => _variantId == NotFoundErrorId; public global::MyApp.NotFoundError AsNotFoundError { get { if (_variantId == NotFoundErrorId) - return _notFoundError!; + return _notFoundError; throw new System.InvalidOperationException("Inner value is not NotFoundError"); } } @@ -76,11 +76,11 @@ public BusinessLogicResult(global::MyApp.NotFoundError notFoundError) public static explicit operator global::MyApp.NotFoundError(BusinessLogicResult value) { if (value._variantId == NotFoundErrorId) - return value._notFoundError!; + return value._notFoundError; throw new System.InvalidOperationException("Inner value is not NotFoundError"); } - public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.NotFoundError? value) + public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.NotFoundError value) { if (_variantId == NotFoundErrorId) { @@ -95,14 +95,14 @@ public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(tru } private const int ValidationErrorId = 3; - private readonly global::MyApp.ValidationError? _validationError; + private readonly global::MyApp.ValidationError _validationError; public bool IsValidationError => _variantId == ValidationErrorId; public global::MyApp.ValidationError AsValidationError { get { if (_variantId == ValidationErrorId) - return _validationError!; + return _validationError; throw new System.InvalidOperationException("Inner value is not ValidationError"); } } @@ -118,11 +118,11 @@ public BusinessLogicResult(global::MyApp.ValidationError validationError) public static explicit operator global::MyApp.ValidationError(BusinessLogicResult value) { if (value._variantId == ValidationErrorId) - return value._validationError!; + return value._validationError; throw new System.InvalidOperationException("Inner value is not ValidationError"); } - public bool TryGetValidationError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.ValidationError? value) + public bool TryGetValidationError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.ValidationError value) { if (_variantId == ValidationErrorId) { @@ -139,22 +139,22 @@ public bool TryGetValidationError([System.Diagnostics.CodeAnalysis.NotNullWhen(t public TOut Match(global::System.Func matchSuccess, global::System.Func matchNotFoundError, global::System.Func matchValidationError) { if (_variantId == SuccessId) - return matchSuccess(_success!); + return matchSuccess(_success); if (_variantId == NotFoundErrorId) - return matchNotFoundError(_notFoundError!); + return matchNotFoundError(_notFoundError); if (_variantId == ValidationErrorId) - return matchValidationError(_validationError!); + return matchValidationError(_validationError); throw new System.InvalidOperationException("Inner type is unknown"); } public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchSuccess, global::System.Func> matchNotFoundError, global::System.Func> matchValidationError, global::System.Threading.CancellationToken ct) { if (_variantId == SuccessId) - return await matchSuccess(_success!, ct).ConfigureAwait(false); + return await matchSuccess(_success, ct).ConfigureAwait(false); if (_variantId == NotFoundErrorId) - return await matchNotFoundError(_notFoundError!, ct).ConfigureAwait(false); + return await matchNotFoundError(_notFoundError, ct).ConfigureAwait(false); if (_variantId == ValidationErrorId) - return await matchValidationError(_validationError!, ct).ConfigureAwait(false); + return await matchValidationError(_validationError, ct).ConfigureAwait(false); throw new System.InvalidOperationException("Inner type is unknown"); } @@ -162,19 +162,19 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - switchSuccess(_success!); + switchSuccess(_success); return; } if (_variantId == NotFoundErrorId) { - switchNotFoundError(_notFoundError!); + switchNotFoundError(_notFoundError); return; } if (_variantId == ValidationErrorId) { - switchValidationError(_validationError!); + switchValidationError(_validationError); return; } @@ -185,19 +185,19 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - await switchSuccess(_success!, ct).ConfigureAwait(false); + await switchSuccess(_success, ct).ConfigureAwait(false); return; } if (_variantId == NotFoundErrorId) { - await switchNotFoundError(_notFoundError!, ct).ConfigureAwait(false); + await switchNotFoundError(_notFoundError, ct).ConfigureAwait(false); return; } if (_variantId == ValidationErrorId) { - await switchValidationError(_validationError!, ct).ConfigureAwait(false); + await switchValidationError(_validationError, ct).ConfigureAwait(false); return; } @@ -257,11 +257,11 @@ public bool Equals(BusinessLogicResult? other) } if (_variantId == SuccessId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_success!, other._success); + return System.Collections.Generic.EqualityComparer.Default.Equals(_success, other._success); if (_variantId == NotFoundErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_notFoundError!, other._notFoundError); + return System.Collections.Generic.EqualityComparer.Default.Equals(_notFoundError, other._notFoundError); if (_variantId == ValidationErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_validationError!, other._validationError); + return System.Collections.Generic.EqualityComparer.Default.Equals(_validationError, other._validationError); throw new System.InvalidOperationException("Inner type is unknown"); } diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ToConverter#DataAccessResult.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ToConverter#DataAccessResult.g.verified.cs index 3fbfac7..d8df1e4 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ToConverter#DataAccessResult.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ToConverter#DataAccessResult.g.verified.cs @@ -11,14 +11,14 @@ partial class DataAccessResult : System.IEquatable { private readonly int _variantId; private const int SuccessId = 1; - private readonly global::MyApp.Success? _success; + private readonly global::MyApp.Success _success; public bool IsSuccess => _variantId == SuccessId; public global::MyApp.Success AsSuccess { get { if (_variantId == SuccessId) - return _success!; + return _success; throw new System.InvalidOperationException("Inner value is not Success"); } } @@ -34,11 +34,11 @@ public DataAccessResult(global::MyApp.Success success) public static explicit operator global::MyApp.Success(DataAccessResult value) { if (value._variantId == SuccessId) - return value._success!; + return value._success; throw new System.InvalidOperationException("Inner value is not Success"); } - public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success? value) + public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success value) { if (_variantId == SuccessId) { @@ -53,14 +53,14 @@ public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] ou } private const int NotFoundErrorId = 2; - private readonly global::MyApp.NotFoundError? _notFoundError; + private readonly global::MyApp.NotFoundError _notFoundError; public bool IsNotFoundError => _variantId == NotFoundErrorId; public global::MyApp.NotFoundError AsNotFoundError { get { if (_variantId == NotFoundErrorId) - return _notFoundError!; + return _notFoundError; throw new System.InvalidOperationException("Inner value is not NotFoundError"); } } @@ -76,11 +76,11 @@ public DataAccessResult(global::MyApp.NotFoundError notFoundError) public static explicit operator global::MyApp.NotFoundError(DataAccessResult value) { if (value._variantId == NotFoundErrorId) - return value._notFoundError!; + return value._notFoundError; throw new System.InvalidOperationException("Inner value is not NotFoundError"); } - public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.NotFoundError? value) + public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.NotFoundError value) { if (_variantId == NotFoundErrorId) { @@ -97,18 +97,18 @@ public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(tru public TOut Match(global::System.Func matchSuccess, global::System.Func matchNotFoundError) { if (_variantId == SuccessId) - return matchSuccess(_success!); + return matchSuccess(_success); if (_variantId == NotFoundErrorId) - return matchNotFoundError(_notFoundError!); + return matchNotFoundError(_notFoundError); throw new System.InvalidOperationException("Inner type is unknown"); } public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchSuccess, global::System.Func> matchNotFoundError, global::System.Threading.CancellationToken ct) { if (_variantId == SuccessId) - return await matchSuccess(_success!, ct).ConfigureAwait(false); + return await matchSuccess(_success, ct).ConfigureAwait(false); if (_variantId == NotFoundErrorId) - return await matchNotFoundError(_notFoundError!, ct).ConfigureAwait(false); + return await matchNotFoundError(_notFoundError, ct).ConfigureAwait(false); throw new System.InvalidOperationException("Inner type is unknown"); } @@ -116,13 +116,13 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - switchSuccess(_success!); + switchSuccess(_success); return; } if (_variantId == NotFoundErrorId) { - switchNotFoundError(_notFoundError!); + switchNotFoundError(_notFoundError); return; } @@ -133,13 +133,13 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - await switchSuccess(_success!, ct).ConfigureAwait(false); + await switchSuccess(_success, ct).ConfigureAwait(false); return; } if (_variantId == NotFoundErrorId) { - await switchNotFoundError(_notFoundError!, ct).ConfigureAwait(false); + await switchNotFoundError(_notFoundError, ct).ConfigureAwait(false); return; } @@ -195,9 +195,9 @@ public bool Equals(DataAccessResult? other) } if (_variantId == SuccessId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_success!, other._success); + return System.Collections.Generic.EqualityComparer.Default.Equals(_success, other._success); if (_variantId == NotFoundErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_notFoundError!, other._notFoundError); + return System.Collections.Generic.EqualityComparer.Default.Equals(_notFoundError, other._notFoundError); throw new System.InvalidOperationException("Inner type is unknown"); } diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ToConverter#GenericUnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ToConverter#GenericUnionTypeAttribute.g.verified.cs index 853ee82..e256764 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ToConverter#GenericUnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ToConverter#GenericUnionTypeAttribute.g.verified.cs @@ -9,8 +9,10 @@ namespace N.SourceGenerators.UnionTypes { - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] + [AttributeUsage(AttributeTargets.GenericParameter, Inherited = false, AllowMultiple = false)] internal sealed class GenericUnionTypeAttribute : Attribute { + public string? Alias { get; set; } + public bool AllowNull { get; set; } } } \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ToConverter#UnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ToConverter#UnionTypeAttribute.g.verified.cs index c9f95c1..c8f7fed 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ToConverter#UnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ToConverter#UnionTypeAttribute.g.verified.cs @@ -15,6 +15,7 @@ internal sealed class UnionTypeAttribute : Attribute public Type Type { get; } public string? Alias { get; } public int Order { get; } + public bool AllowNull { get; set; } public UnionTypeAttribute(Type type, string? alias = null, [CallerLineNumber] int order = 0) { diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ToConverterReportsDiagnostic#BusinessLogicResult.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ToConverterReportsDiagnostic#BusinessLogicResult.g.verified.cs index 51e8e1d..c2d5398 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ToConverterReportsDiagnostic#BusinessLogicResult.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ToConverterReportsDiagnostic#BusinessLogicResult.g.verified.cs @@ -11,14 +11,14 @@ partial class BusinessLogicResult : System.IEquatable { private readonly int _variantId; private const int NotFoundErrorId = 1; - private readonly global::MyApp.NotFoundError? _notFoundError; + private readonly global::MyApp.NotFoundError _notFoundError; public bool IsNotFoundError => _variantId == NotFoundErrorId; public global::MyApp.NotFoundError AsNotFoundError { get { if (_variantId == NotFoundErrorId) - return _notFoundError!; + return _notFoundError; throw new System.InvalidOperationException("Inner value is not NotFoundError"); } } @@ -34,11 +34,11 @@ public BusinessLogicResult(global::MyApp.NotFoundError notFoundError) public static explicit operator global::MyApp.NotFoundError(BusinessLogicResult value) { if (value._variantId == NotFoundErrorId) - return value._notFoundError!; + return value._notFoundError; throw new System.InvalidOperationException("Inner value is not NotFoundError"); } - public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.NotFoundError? value) + public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.NotFoundError value) { if (_variantId == NotFoundErrorId) { @@ -53,14 +53,14 @@ public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(tru } private const int ValidationErrorId = 2; - private readonly global::MyApp.ValidationError? _validationError; + private readonly global::MyApp.ValidationError _validationError; public bool IsValidationError => _variantId == ValidationErrorId; public global::MyApp.ValidationError AsValidationError { get { if (_variantId == ValidationErrorId) - return _validationError!; + return _validationError; throw new System.InvalidOperationException("Inner value is not ValidationError"); } } @@ -76,11 +76,11 @@ public BusinessLogicResult(global::MyApp.ValidationError validationError) public static explicit operator global::MyApp.ValidationError(BusinessLogicResult value) { if (value._variantId == ValidationErrorId) - return value._validationError!; + return value._validationError; throw new System.InvalidOperationException("Inner value is not ValidationError"); } - public bool TryGetValidationError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.ValidationError? value) + public bool TryGetValidationError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.ValidationError value) { if (_variantId == ValidationErrorId) { @@ -97,18 +97,18 @@ public bool TryGetValidationError([System.Diagnostics.CodeAnalysis.NotNullWhen(t public TOut Match(global::System.Func matchNotFoundError, global::System.Func matchValidationError) { if (_variantId == NotFoundErrorId) - return matchNotFoundError(_notFoundError!); + return matchNotFoundError(_notFoundError); if (_variantId == ValidationErrorId) - return matchValidationError(_validationError!); + return matchValidationError(_validationError); throw new System.InvalidOperationException("Inner type is unknown"); } public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchNotFoundError, global::System.Func> matchValidationError, global::System.Threading.CancellationToken ct) { if (_variantId == NotFoundErrorId) - return await matchNotFoundError(_notFoundError!, ct).ConfigureAwait(false); + return await matchNotFoundError(_notFoundError, ct).ConfigureAwait(false); if (_variantId == ValidationErrorId) - return await matchValidationError(_validationError!, ct).ConfigureAwait(false); + return await matchValidationError(_validationError, ct).ConfigureAwait(false); throw new System.InvalidOperationException("Inner type is unknown"); } @@ -116,13 +116,13 @@ public void Switch(global::System.Action switchNotF { if (_variantId == NotFoundErrorId) { - switchNotFoundError(_notFoundError!); + switchNotFoundError(_notFoundError); return; } if (_variantId == ValidationErrorId) { - switchValidationError(_validationError!); + switchValidationError(_validationError); return; } @@ -133,13 +133,13 @@ public void Switch(global::System.Action switchNotF { if (_variantId == NotFoundErrorId) { - await switchNotFoundError(_notFoundError!, ct).ConfigureAwait(false); + await switchNotFoundError(_notFoundError, ct).ConfigureAwait(false); return; } if (_variantId == ValidationErrorId) { - await switchValidationError(_validationError!, ct).ConfigureAwait(false); + await switchValidationError(_validationError, ct).ConfigureAwait(false); return; } @@ -195,9 +195,9 @@ public bool Equals(BusinessLogicResult? other) } if (_variantId == NotFoundErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_notFoundError!, other._notFoundError); + return System.Collections.Generic.EqualityComparer.Default.Equals(_notFoundError, other._notFoundError); if (_variantId == ValidationErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_validationError!, other._validationError); + return System.Collections.Generic.EqualityComparer.Default.Equals(_validationError, other._validationError); throw new System.InvalidOperationException("Inner type is unknown"); } diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ToConverterReportsDiagnostic#DataAccessResult.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ToConverterReportsDiagnostic#DataAccessResult.g.verified.cs index 3fbfac7..d8df1e4 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ToConverterReportsDiagnostic#DataAccessResult.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ToConverterReportsDiagnostic#DataAccessResult.g.verified.cs @@ -11,14 +11,14 @@ partial class DataAccessResult : System.IEquatable { private readonly int _variantId; private const int SuccessId = 1; - private readonly global::MyApp.Success? _success; + private readonly global::MyApp.Success _success; public bool IsSuccess => _variantId == SuccessId; public global::MyApp.Success AsSuccess { get { if (_variantId == SuccessId) - return _success!; + return _success; throw new System.InvalidOperationException("Inner value is not Success"); } } @@ -34,11 +34,11 @@ public DataAccessResult(global::MyApp.Success success) public static explicit operator global::MyApp.Success(DataAccessResult value) { if (value._variantId == SuccessId) - return value._success!; + return value._success; throw new System.InvalidOperationException("Inner value is not Success"); } - public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success? value) + public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success value) { if (_variantId == SuccessId) { @@ -53,14 +53,14 @@ public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] ou } private const int NotFoundErrorId = 2; - private readonly global::MyApp.NotFoundError? _notFoundError; + private readonly global::MyApp.NotFoundError _notFoundError; public bool IsNotFoundError => _variantId == NotFoundErrorId; public global::MyApp.NotFoundError AsNotFoundError { get { if (_variantId == NotFoundErrorId) - return _notFoundError!; + return _notFoundError; throw new System.InvalidOperationException("Inner value is not NotFoundError"); } } @@ -76,11 +76,11 @@ public DataAccessResult(global::MyApp.NotFoundError notFoundError) public static explicit operator global::MyApp.NotFoundError(DataAccessResult value) { if (value._variantId == NotFoundErrorId) - return value._notFoundError!; + return value._notFoundError; throw new System.InvalidOperationException("Inner value is not NotFoundError"); } - public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.NotFoundError? value) + public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.NotFoundError value) { if (_variantId == NotFoundErrorId) { @@ -97,18 +97,18 @@ public bool TryGetNotFoundError([System.Diagnostics.CodeAnalysis.NotNullWhen(tru public TOut Match(global::System.Func matchSuccess, global::System.Func matchNotFoundError) { if (_variantId == SuccessId) - return matchSuccess(_success!); + return matchSuccess(_success); if (_variantId == NotFoundErrorId) - return matchNotFoundError(_notFoundError!); + return matchNotFoundError(_notFoundError); throw new System.InvalidOperationException("Inner type is unknown"); } public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchSuccess, global::System.Func> matchNotFoundError, global::System.Threading.CancellationToken ct) { if (_variantId == SuccessId) - return await matchSuccess(_success!, ct).ConfigureAwait(false); + return await matchSuccess(_success, ct).ConfigureAwait(false); if (_variantId == NotFoundErrorId) - return await matchNotFoundError(_notFoundError!, ct).ConfigureAwait(false); + return await matchNotFoundError(_notFoundError, ct).ConfigureAwait(false); throw new System.InvalidOperationException("Inner type is unknown"); } @@ -116,13 +116,13 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - switchSuccess(_success!); + switchSuccess(_success); return; } if (_variantId == NotFoundErrorId) { - switchNotFoundError(_notFoundError!); + switchNotFoundError(_notFoundError); return; } @@ -133,13 +133,13 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - await switchSuccess(_success!, ct).ConfigureAwait(false); + await switchSuccess(_success, ct).ConfigureAwait(false); return; } if (_variantId == NotFoundErrorId) { - await switchNotFoundError(_notFoundError!, ct).ConfigureAwait(false); + await switchNotFoundError(_notFoundError, ct).ConfigureAwait(false); return; } @@ -195,9 +195,9 @@ public bool Equals(DataAccessResult? other) } if (_variantId == SuccessId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_success!, other._success); + return System.Collections.Generic.EqualityComparer.Default.Equals(_success, other._success); if (_variantId == NotFoundErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_notFoundError!, other._notFoundError); + return System.Collections.Generic.EqualityComparer.Default.Equals(_notFoundError, other._notFoundError); throw new System.InvalidOperationException("Inner type is unknown"); } diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ToConverterReportsDiagnostic#GenericUnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ToConverterReportsDiagnostic#GenericUnionTypeAttribute.g.verified.cs index 853ee82..e256764 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ToConverterReportsDiagnostic#GenericUnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ToConverterReportsDiagnostic#GenericUnionTypeAttribute.g.verified.cs @@ -9,8 +9,10 @@ namespace N.SourceGenerators.UnionTypes { - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] + [AttributeUsage(AttributeTargets.GenericParameter, Inherited = false, AllowMultiple = false)] internal sealed class GenericUnionTypeAttribute : Attribute { + public string? Alias { get; set; } + public bool AllowNull { get; set; } } } \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ToConverterReportsDiagnostic#UnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ToConverterReportsDiagnostic#UnionTypeAttribute.g.verified.cs index c9f95c1..c8f7fed 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ToConverterReportsDiagnostic#UnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/ConverterGeneratorTests.ToConverterReportsDiagnostic#UnionTypeAttribute.g.verified.cs @@ -15,6 +15,7 @@ internal sealed class UnionTypeAttribute : Attribute public Type Type { get; } public string? Alias { get; } public int Order { get; } + public bool AllowNull { get; set; } public UnionTypeAttribute(Type type, string? alias = null, [CallerLineNumber] int order = 0) { diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.InvalidTypeReportsAllDiagnostics#GenericUnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.InvalidTypeReportsAllDiagnostics#GenericUnionTypeAttribute.g.verified.cs index 853ee82..e256764 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.InvalidTypeReportsAllDiagnostics#GenericUnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.InvalidTypeReportsAllDiagnostics#GenericUnionTypeAttribute.g.verified.cs @@ -9,8 +9,10 @@ namespace N.SourceGenerators.UnionTypes { - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] + [AttributeUsage(AttributeTargets.GenericParameter, Inherited = false, AllowMultiple = false)] internal sealed class GenericUnionTypeAttribute : Attribute { + public string? Alias { get; set; } + public bool AllowNull { get; set; } } } \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.InvalidTypeReportsAllDiagnostics#UnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.InvalidTypeReportsAllDiagnostics#UnionTypeAttribute.g.verified.cs index c9f95c1..c8f7fed 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.InvalidTypeReportsAllDiagnostics#UnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.InvalidTypeReportsAllDiagnostics#UnionTypeAttribute.g.verified.cs @@ -15,6 +15,7 @@ internal sealed class UnionTypeAttribute : Attribute public Type Type { get; } public string? Alias { get; } public int Order { get; } + public bool AllowNull { get; set; } public UnionTypeAttribute(Type type, string? alias = null, [CallerLineNumber] int order = 0) { diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.NotPartialTypeReportsDiagnostics#GenericUnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.NotPartialTypeReportsDiagnostics#GenericUnionTypeAttribute.g.verified.cs index 853ee82..e256764 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.NotPartialTypeReportsDiagnostics#GenericUnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.NotPartialTypeReportsDiagnostics#GenericUnionTypeAttribute.g.verified.cs @@ -9,8 +9,10 @@ namespace N.SourceGenerators.UnionTypes { - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] + [AttributeUsage(AttributeTargets.GenericParameter, Inherited = false, AllowMultiple = false)] internal sealed class GenericUnionTypeAttribute : Attribute { + public string? Alias { get; set; } + public bool AllowNull { get; set; } } } \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.NotPartialTypeReportsDiagnostics#UnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.NotPartialTypeReportsDiagnostics#UnionTypeAttribute.g.verified.cs index c9f95c1..c8f7fed 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.NotPartialTypeReportsDiagnostics#UnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.NotPartialTypeReportsDiagnostics#UnionTypeAttribute.g.verified.cs @@ -15,6 +15,7 @@ internal sealed class UnionTypeAttribute : Attribute public Type Type { get; } public string? Alias { get; } public int Order { get; } + public bool AllowNull { get; set; } public UnionTypeAttribute(Type type, string? alias = null, [CallerLineNumber] int order = 0) { diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.VariantAliasDuplicateReportsDiagnostics#GenericUnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.VariantAliasDuplicateReportsDiagnostics#GenericUnionTypeAttribute.g.verified.cs index 853ee82..e256764 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.VariantAliasDuplicateReportsDiagnostics#GenericUnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.VariantAliasDuplicateReportsDiagnostics#GenericUnionTypeAttribute.g.verified.cs @@ -9,8 +9,10 @@ namespace N.SourceGenerators.UnionTypes { - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] + [AttributeUsage(AttributeTargets.GenericParameter, Inherited = false, AllowMultiple = false)] internal sealed class GenericUnionTypeAttribute : Attribute { + public string? Alias { get; set; } + public bool AllowNull { get; set; } } } \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.VariantAliasDuplicateReportsDiagnostics#UnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.VariantAliasDuplicateReportsDiagnostics#UnionTypeAttribute.g.verified.cs index c9f95c1..c8f7fed 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.VariantAliasDuplicateReportsDiagnostics#UnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.VariantAliasDuplicateReportsDiagnostics#UnionTypeAttribute.g.verified.cs @@ -15,6 +15,7 @@ internal sealed class UnionTypeAttribute : Attribute public Type Type { get; } public string? Alias { get; } public int Order { get; } + public bool AllowNull { get; set; } public UnionTypeAttribute(Type type, string? alias = null, [CallerLineNumber] int order = 0) { diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.VariantOrderDuplicateReportsDiagnostics#GenericUnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.VariantOrderDuplicateReportsDiagnostics#GenericUnionTypeAttribute.g.verified.cs index 853ee82..e256764 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.VariantOrderDuplicateReportsDiagnostics#GenericUnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.VariantOrderDuplicateReportsDiagnostics#GenericUnionTypeAttribute.g.verified.cs @@ -9,8 +9,10 @@ namespace N.SourceGenerators.UnionTypes { - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] + [AttributeUsage(AttributeTargets.GenericParameter, Inherited = false, AllowMultiple = false)] internal sealed class GenericUnionTypeAttribute : Attribute { + public string? Alias { get; set; } + public bool AllowNull { get; set; } } } \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.VariantOrderDuplicateReportsDiagnostics#UnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.VariantOrderDuplicateReportsDiagnostics#UnionTypeAttribute.g.verified.cs index c9f95c1..c8f7fed 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.VariantOrderDuplicateReportsDiagnostics#UnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.VariantOrderDuplicateReportsDiagnostics#UnionTypeAttribute.g.verified.cs @@ -15,6 +15,7 @@ internal sealed class UnionTypeAttribute : Attribute public Type Type { get; } public string? Alias { get; } public int Order { get; } + public bool AllowNull { get; set; } public UnionTypeAttribute(Type type, string? alias = null, [CallerLineNumber] int order = 0) { diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.VariantTypeDuplicateReportsDiagnostics#GenericUnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.VariantTypeDuplicateReportsDiagnostics#GenericUnionTypeAttribute.g.verified.cs index 853ee82..e256764 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.VariantTypeDuplicateReportsDiagnostics#GenericUnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.VariantTypeDuplicateReportsDiagnostics#GenericUnionTypeAttribute.g.verified.cs @@ -9,8 +9,10 @@ namespace N.SourceGenerators.UnionTypes { - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] + [AttributeUsage(AttributeTargets.GenericParameter, Inherited = false, AllowMultiple = false)] internal sealed class GenericUnionTypeAttribute : Attribute { + public string? Alias { get; set; } + public bool AllowNull { get; set; } } } \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.VariantTypeDuplicateReportsDiagnostics#UnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.VariantTypeDuplicateReportsDiagnostics#UnionTypeAttribute.g.verified.cs index c9f95c1..c8f7fed 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.VariantTypeDuplicateReportsDiagnostics#UnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/DiagnosticTests.VariantTypeDuplicateReportsDiagnostics#UnionTypeAttribute.g.verified.cs @@ -15,6 +15,7 @@ internal sealed class UnionTypeAttribute : Attribute public Type Type { get; } public string? Alias { get; } public int Order { get; } + public bool AllowNull { get; set; } public UnionTypeAttribute(Type type, string? alias = null, [CallerLineNumber] int order = 0) { diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DifferentNamespaces#GenericUnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DifferentNamespaces#GenericUnionTypeAttribute.g.verified.cs index 853ee82..e256764 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DifferentNamespaces#GenericUnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DifferentNamespaces#GenericUnionTypeAttribute.g.verified.cs @@ -9,8 +9,10 @@ namespace N.SourceGenerators.UnionTypes { - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] + [AttributeUsage(AttributeTargets.GenericParameter, Inherited = false, AllowMultiple = false)] internal sealed class GenericUnionTypeAttribute : Attribute { + public string? Alias { get; set; } + public bool AllowNull { get; set; } } } \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DifferentNamespaces#Result.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DifferentNamespaces#Result.g.verified.cs index c828fc5..db780f9 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DifferentNamespaces#Result.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DifferentNamespaces#Result.g.verified.cs @@ -11,14 +11,14 @@ partial class Result : System.IEquatable { private readonly int _variantId; private const int SuccessId = 1; - private readonly global::MyApp.Models.S.Child.Success? _success; + private readonly global::MyApp.Models.S.Child.Success _success; public bool IsSuccess => _variantId == SuccessId; public global::MyApp.Models.S.Child.Success AsSuccess { get { if (_variantId == SuccessId) - return _success!; + return _success; throw new System.InvalidOperationException("Inner value is not Success"); } } @@ -34,11 +34,11 @@ public Result(global::MyApp.Models.S.Child.Success success) public static explicit operator global::MyApp.Models.S.Child.Success(Result value) { if (value._variantId == SuccessId) - return value._success!; + return value._success; throw new System.InvalidOperationException("Inner value is not Success"); } - public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Models.S.Child.Success? value) + public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Models.S.Child.Success value) { if (_variantId == SuccessId) { @@ -53,14 +53,14 @@ public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] ou } private const int ErrorId = 2; - private readonly global::MyApp.Models.E.Child.Error? _error; + private readonly global::MyApp.Models.E.Child.Error _error; public bool IsError => _variantId == ErrorId; public global::MyApp.Models.E.Child.Error AsError { get { if (_variantId == ErrorId) - return _error!; + return _error; throw new System.InvalidOperationException("Inner value is not Error"); } } @@ -76,11 +76,11 @@ public Result(global::MyApp.Models.E.Child.Error @error) public static explicit operator global::MyApp.Models.E.Child.Error(Result value) { if (value._variantId == ErrorId) - return value._error!; + return value._error; throw new System.InvalidOperationException("Inner value is not Error"); } - public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Models.E.Child.Error? value) + public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Models.E.Child.Error value) { if (_variantId == ErrorId) { @@ -97,18 +97,18 @@ public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out public TOut Match(global::System.Func matchSuccess, global::System.Func matchError) { if (_variantId == SuccessId) - return matchSuccess(_success!); + return matchSuccess(_success); if (_variantId == ErrorId) - return matchError(_error!); + return matchError(_error); throw new System.InvalidOperationException("Inner type is unknown"); } public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchSuccess, global::System.Func> matchError, global::System.Threading.CancellationToken ct) { if (_variantId == SuccessId) - return await matchSuccess(_success!, ct).ConfigureAwait(false); + return await matchSuccess(_success, ct).ConfigureAwait(false); if (_variantId == ErrorId) - return await matchError(_error!, ct).ConfigureAwait(false); + return await matchError(_error, ct).ConfigureAwait(false); throw new System.InvalidOperationException("Inner type is unknown"); } @@ -116,13 +116,13 @@ public void Switch(global::System.Action s { if (_variantId == SuccessId) { - switchSuccess(_success!); + switchSuccess(_success); return; } if (_variantId == ErrorId) { - switchError(_error!); + switchError(_error); return; } @@ -133,13 +133,13 @@ public void Switch(global::System.Action s { if (_variantId == SuccessId) { - await switchSuccess(_success!, ct).ConfigureAwait(false); + await switchSuccess(_success, ct).ConfigureAwait(false); return; } if (_variantId == ErrorId) { - await switchError(_error!, ct).ConfigureAwait(false); + await switchError(_error, ct).ConfigureAwait(false); return; } @@ -195,9 +195,9 @@ public bool Equals(Result? other) } if (_variantId == SuccessId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_success!, other._success); + return System.Collections.Generic.EqualityComparer.Default.Equals(_success, other._success); if (_variantId == ErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_error!, other._error); + return System.Collections.Generic.EqualityComparer.Default.Equals(_error, other._error); throw new System.InvalidOperationException("Inner type is unknown"); } diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DifferentNamespaces#UnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DifferentNamespaces#UnionTypeAttribute.g.verified.cs index c9f95c1..c8f7fed 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DifferentNamespaces#UnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DifferentNamespaces#UnionTypeAttribute.g.verified.cs @@ -15,6 +15,7 @@ internal sealed class UnionTypeAttribute : Attribute public Type Type { get; } public string? Alias { get; } public int Order { get; } + public bool AllowNull { get; set; } public UnionTypeAttribute(Type type, string? alias = null, [CallerLineNumber] int order = 0) { diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_partial-class#GenericUnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_partial-class#GenericUnionTypeAttribute.g.verified.cs index 853ee82..e256764 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_partial-class#GenericUnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_partial-class#GenericUnionTypeAttribute.g.verified.cs @@ -9,8 +9,10 @@ namespace N.SourceGenerators.UnionTypes { - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] + [AttributeUsage(AttributeTargets.GenericParameter, Inherited = false, AllowMultiple = false)] internal sealed class GenericUnionTypeAttribute : Attribute { + public string? Alias { get; set; } + public bool AllowNull { get; set; } } } \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_partial-class#Result.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_partial-class#Result.g.verified.cs index 6e580bb..6030546 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_partial-class#Result.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_partial-class#Result.g.verified.cs @@ -11,14 +11,14 @@ partial class Result : System.IEquatable { private readonly int _variantId; private const int SuccessId = 1; - private readonly global::MyApp.Success? _success; + private readonly global::MyApp.Success _success; public bool IsSuccess => _variantId == SuccessId; public global::MyApp.Success AsSuccess { get { if (_variantId == SuccessId) - return _success!; + return _success; throw new System.InvalidOperationException("Inner value is not Success"); } } @@ -34,11 +34,11 @@ public Result(global::MyApp.Success success) public static explicit operator global::MyApp.Success(Result value) { if (value._variantId == SuccessId) - return value._success!; + return value._success; throw new System.InvalidOperationException("Inner value is not Success"); } - public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success? value) + public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success value) { if (_variantId == SuccessId) { @@ -53,14 +53,14 @@ public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] ou } private const int ErrorId = 2; - private readonly global::MyApp.Error? _error; + private readonly global::MyApp.Error _error; public bool IsError => _variantId == ErrorId; public global::MyApp.Error AsError { get { if (_variantId == ErrorId) - return _error!; + return _error; throw new System.InvalidOperationException("Inner value is not Error"); } } @@ -76,11 +76,11 @@ public Result(global::MyApp.Error @error) public static explicit operator global::MyApp.Error(Result value) { if (value._variantId == ErrorId) - return value._error!; + return value._error; throw new System.InvalidOperationException("Inner value is not Error"); } - public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Error? value) + public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Error value) { if (_variantId == ErrorId) { @@ -95,14 +95,14 @@ public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out } private const int IReadOnlyListOfInt32Id = 3; - private readonly global::System.Collections.Generic.IReadOnlyList? _iReadOnlyListOfInt32; + private readonly global::System.Collections.Generic.IReadOnlyList _iReadOnlyListOfInt32; public bool IsIReadOnlyListOfInt32 => _variantId == IReadOnlyListOfInt32Id; public global::System.Collections.Generic.IReadOnlyList AsIReadOnlyListOfInt32 { get { if (_variantId == IReadOnlyListOfInt32Id) - return _iReadOnlyListOfInt32!; + return _iReadOnlyListOfInt32; throw new System.InvalidOperationException("Inner value is not IReadOnlyListOfInt32"); } } @@ -114,7 +114,7 @@ public Result(global::System.Collections.Generic.IReadOnlyList iReadOnlyLis _iReadOnlyListOfInt32 = iReadOnlyListOfInt32; } - public bool TryGetIReadOnlyListOfInt32([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::System.Collections.Generic.IReadOnlyList? value) + public bool TryGetIReadOnlyListOfInt32([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::System.Collections.Generic.IReadOnlyList value) { if (_variantId == IReadOnlyListOfInt32Id) { @@ -129,14 +129,14 @@ public bool TryGetIReadOnlyListOfInt32([System.Diagnostics.CodeAnalysis.NotNullW } private const int ArrayOfStringId = 4; - private readonly string[]? _arrayOfString; + private readonly string[] _arrayOfString; public bool IsArrayOfString => _variantId == ArrayOfStringId; public string[] AsArrayOfString { get { if (_variantId == ArrayOfStringId) - return _arrayOfString!; + return _arrayOfString; throw new System.InvalidOperationException("Inner value is not ArrayOfString"); } } @@ -152,11 +152,11 @@ public Result(string[] arrayOfString) public static explicit operator string[](Result value) { if (value._variantId == ArrayOfStringId) - return value._arrayOfString!; + return value._arrayOfString; throw new System.InvalidOperationException("Inner value is not ArrayOfString"); } - public bool TryGetArrayOfString([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out string[]? value) + public bool TryGetArrayOfString([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out string[] value) { if (_variantId == ArrayOfStringId) { @@ -171,14 +171,14 @@ public bool TryGetArrayOfString([System.Diagnostics.CodeAnalysis.NotNullWhen(tru } private const int TupleOfInt32AndStringId = 5; - private readonly global::System.Tuple? _tupleOfInt32AndString; + private readonly global::System.Tuple _tupleOfInt32AndString; public bool IsTupleOfInt32AndString => _variantId == TupleOfInt32AndStringId; public global::System.Tuple AsTupleOfInt32AndString { get { if (_variantId == TupleOfInt32AndStringId) - return _tupleOfInt32AndString!; + return _tupleOfInt32AndString; throw new System.InvalidOperationException("Inner value is not TupleOfInt32AndString"); } } @@ -194,11 +194,11 @@ public Result(global::System.Tuple tupleOfInt32AndString) public static explicit operator global::System.Tuple(Result value) { if (value._variantId == TupleOfInt32AndStringId) - return value._tupleOfInt32AndString!; + return value._tupleOfInt32AndString; throw new System.InvalidOperationException("Inner value is not TupleOfInt32AndString"); } - public bool TryGetTupleOfInt32AndString([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::System.Tuple? value) + public bool TryGetTupleOfInt32AndString([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::System.Tuple value) { if (_variantId == TupleOfInt32AndStringId) { @@ -215,30 +215,30 @@ public bool TryGetTupleOfInt32AndString([System.Diagnostics.CodeAnalysis.NotNull public TOut Match(global::System.Func matchSuccess, global::System.Func matchError, global::System.Func, TOut> matchIReadOnlyListOfInt32, global::System.Func matchArrayOfString, global::System.Func, TOut> matchTupleOfInt32AndString) { if (_variantId == SuccessId) - return matchSuccess(_success!); + return matchSuccess(_success); if (_variantId == ErrorId) - return matchError(_error!); + return matchError(_error); if (_variantId == IReadOnlyListOfInt32Id) - return matchIReadOnlyListOfInt32(_iReadOnlyListOfInt32!); + return matchIReadOnlyListOfInt32(_iReadOnlyListOfInt32); if (_variantId == ArrayOfStringId) - return matchArrayOfString(_arrayOfString!); + return matchArrayOfString(_arrayOfString); if (_variantId == TupleOfInt32AndStringId) - return matchTupleOfInt32AndString(_tupleOfInt32AndString!); + return matchTupleOfInt32AndString(_tupleOfInt32AndString); throw new System.InvalidOperationException("Inner type is unknown"); } public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchSuccess, global::System.Func> matchError, global::System.Func, global::System.Threading.CancellationToken, global::System.Threading.Tasks.Task> matchIReadOnlyListOfInt32, global::System.Func> matchArrayOfString, global::System.Func, global::System.Threading.CancellationToken, global::System.Threading.Tasks.Task> matchTupleOfInt32AndString, global::System.Threading.CancellationToken ct) { if (_variantId == SuccessId) - return await matchSuccess(_success!, ct).ConfigureAwait(false); + return await matchSuccess(_success, ct).ConfigureAwait(false); if (_variantId == ErrorId) - return await matchError(_error!, ct).ConfigureAwait(false); + return await matchError(_error, ct).ConfigureAwait(false); if (_variantId == IReadOnlyListOfInt32Id) - return await matchIReadOnlyListOfInt32(_iReadOnlyListOfInt32!, ct).ConfigureAwait(false); + return await matchIReadOnlyListOfInt32(_iReadOnlyListOfInt32, ct).ConfigureAwait(false); if (_variantId == ArrayOfStringId) - return await matchArrayOfString(_arrayOfString!, ct).ConfigureAwait(false); + return await matchArrayOfString(_arrayOfString, ct).ConfigureAwait(false); if (_variantId == TupleOfInt32AndStringId) - return await matchTupleOfInt32AndString(_tupleOfInt32AndString!, ct).ConfigureAwait(false); + return await matchTupleOfInt32AndString(_tupleOfInt32AndString, ct).ConfigureAwait(false); throw new System.InvalidOperationException("Inner type is unknown"); } @@ -246,31 +246,31 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - switchSuccess(_success!); + switchSuccess(_success); return; } if (_variantId == ErrorId) { - switchError(_error!); + switchError(_error); return; } if (_variantId == IReadOnlyListOfInt32Id) { - switchIReadOnlyListOfInt32(_iReadOnlyListOfInt32!); + switchIReadOnlyListOfInt32(_iReadOnlyListOfInt32); return; } if (_variantId == ArrayOfStringId) { - switchArrayOfString(_arrayOfString!); + switchArrayOfString(_arrayOfString); return; } if (_variantId == TupleOfInt32AndStringId) { - switchTupleOfInt32AndString(_tupleOfInt32AndString!); + switchTupleOfInt32AndString(_tupleOfInt32AndString); return; } @@ -281,31 +281,31 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - await switchSuccess(_success!, ct).ConfigureAwait(false); + await switchSuccess(_success, ct).ConfigureAwait(false); return; } if (_variantId == ErrorId) { - await switchError(_error!, ct).ConfigureAwait(false); + await switchError(_error, ct).ConfigureAwait(false); return; } if (_variantId == IReadOnlyListOfInt32Id) { - await switchIReadOnlyListOfInt32(_iReadOnlyListOfInt32!, ct).ConfigureAwait(false); + await switchIReadOnlyListOfInt32(_iReadOnlyListOfInt32, ct).ConfigureAwait(false); return; } if (_variantId == ArrayOfStringId) { - await switchArrayOfString(_arrayOfString!, ct).ConfigureAwait(false); + await switchArrayOfString(_arrayOfString, ct).ConfigureAwait(false); return; } if (_variantId == TupleOfInt32AndStringId) { - await switchTupleOfInt32AndString(_tupleOfInt32AndString!, ct).ConfigureAwait(false); + await switchTupleOfInt32AndString(_tupleOfInt32AndString, ct).ConfigureAwait(false); return; } @@ -373,15 +373,15 @@ public bool Equals(Result? other) } if (_variantId == SuccessId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_success!, other._success); + return System.Collections.Generic.EqualityComparer.Default.Equals(_success, other._success); if (_variantId == ErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_error!, other._error); + return System.Collections.Generic.EqualityComparer.Default.Equals(_error, other._error); if (_variantId == IReadOnlyListOfInt32Id) - return System.Collections.Generic.EqualityComparer>.Default.Equals(_iReadOnlyListOfInt32!, other._iReadOnlyListOfInt32); + return System.Collections.Generic.EqualityComparer>.Default.Equals(_iReadOnlyListOfInt32, other._iReadOnlyListOfInt32); if (_variantId == ArrayOfStringId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_arrayOfString!, other._arrayOfString); + return System.Collections.Generic.EqualityComparer.Default.Equals(_arrayOfString, other._arrayOfString); if (_variantId == TupleOfInt32AndStringId) - return System.Collections.Generic.EqualityComparer>.Default.Equals(_tupleOfInt32AndString!, other._tupleOfInt32AndString); + return System.Collections.Generic.EqualityComparer>.Default.Equals(_tupleOfInt32AndString, other._tupleOfInt32AndString); throw new System.InvalidOperationException("Inner type is unknown"); } diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_partial-class#UnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_partial-class#UnionTypeAttribute.g.verified.cs index c9f95c1..c8f7fed 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_partial-class#UnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_partial-class#UnionTypeAttribute.g.verified.cs @@ -15,6 +15,7 @@ internal sealed class UnionTypeAttribute : Attribute public Type Type { get; } public string? Alias { get; } public int Order { get; } + public bool AllowNull { get; set; } public UnionTypeAttribute(Type type, string? alias = null, [CallerLineNumber] int order = 0) { diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_partial-struct#GenericUnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_partial-struct#GenericUnionTypeAttribute.g.verified.cs index 853ee82..e256764 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_partial-struct#GenericUnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_partial-struct#GenericUnionTypeAttribute.g.verified.cs @@ -9,8 +9,10 @@ namespace N.SourceGenerators.UnionTypes { - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] + [AttributeUsage(AttributeTargets.GenericParameter, Inherited = false, AllowMultiple = false)] internal sealed class GenericUnionTypeAttribute : Attribute { + public string? Alias { get; set; } + public bool AllowNull { get; set; } } } \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_partial-struct#Result.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_partial-struct#Result.g.verified.cs index 83760ac..4fa2c8a 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_partial-struct#Result.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_partial-struct#Result.g.verified.cs @@ -11,14 +11,14 @@ partial struct Result : System.IEquatable { private readonly int _variantId; private const int SuccessId = 1; - private readonly global::MyApp.Success? _success; + private readonly global::MyApp.Success _success; public bool IsSuccess => _variantId == SuccessId; public global::MyApp.Success AsSuccess { get { if (_variantId == SuccessId) - return _success!; + return _success; throw new System.InvalidOperationException("Inner value is not Success"); } } @@ -34,11 +34,11 @@ public Result(global::MyApp.Success success) public static explicit operator global::MyApp.Success(Result value) { if (value._variantId == SuccessId) - return value._success!; + return value._success; throw new System.InvalidOperationException("Inner value is not Success"); } - public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success? value) + public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success value) { if (_variantId == SuccessId) { @@ -53,14 +53,14 @@ public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] ou } private const int ErrorId = 2; - private readonly global::MyApp.Error? _error; + private readonly global::MyApp.Error _error; public bool IsError => _variantId == ErrorId; public global::MyApp.Error AsError { get { if (_variantId == ErrorId) - return _error!; + return _error; throw new System.InvalidOperationException("Inner value is not Error"); } } @@ -76,11 +76,11 @@ public Result(global::MyApp.Error @error) public static explicit operator global::MyApp.Error(Result value) { if (value._variantId == ErrorId) - return value._error!; + return value._error; throw new System.InvalidOperationException("Inner value is not Error"); } - public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Error? value) + public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Error value) { if (_variantId == ErrorId) { @@ -95,14 +95,14 @@ public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out } private const int IReadOnlyListOfInt32Id = 3; - private readonly global::System.Collections.Generic.IReadOnlyList? _iReadOnlyListOfInt32; + private readonly global::System.Collections.Generic.IReadOnlyList _iReadOnlyListOfInt32; public bool IsIReadOnlyListOfInt32 => _variantId == IReadOnlyListOfInt32Id; public global::System.Collections.Generic.IReadOnlyList AsIReadOnlyListOfInt32 { get { if (_variantId == IReadOnlyListOfInt32Id) - return _iReadOnlyListOfInt32!; + return _iReadOnlyListOfInt32; throw new System.InvalidOperationException("Inner value is not IReadOnlyListOfInt32"); } } @@ -114,7 +114,7 @@ public Result(global::System.Collections.Generic.IReadOnlyList iReadOnlyLis _iReadOnlyListOfInt32 = iReadOnlyListOfInt32; } - public bool TryGetIReadOnlyListOfInt32([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::System.Collections.Generic.IReadOnlyList? value) + public bool TryGetIReadOnlyListOfInt32([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::System.Collections.Generic.IReadOnlyList value) { if (_variantId == IReadOnlyListOfInt32Id) { @@ -129,14 +129,14 @@ public bool TryGetIReadOnlyListOfInt32([System.Diagnostics.CodeAnalysis.NotNullW } private const int ArrayOfStringId = 4; - private readonly string[]? _arrayOfString; + private readonly string[] _arrayOfString; public bool IsArrayOfString => _variantId == ArrayOfStringId; public string[] AsArrayOfString { get { if (_variantId == ArrayOfStringId) - return _arrayOfString!; + return _arrayOfString; throw new System.InvalidOperationException("Inner value is not ArrayOfString"); } } @@ -152,11 +152,11 @@ public Result(string[] arrayOfString) public static explicit operator string[](Result value) { if (value._variantId == ArrayOfStringId) - return value._arrayOfString!; + return value._arrayOfString; throw new System.InvalidOperationException("Inner value is not ArrayOfString"); } - public bool TryGetArrayOfString([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out string[]? value) + public bool TryGetArrayOfString([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out string[] value) { if (_variantId == ArrayOfStringId) { @@ -171,14 +171,14 @@ public bool TryGetArrayOfString([System.Diagnostics.CodeAnalysis.NotNullWhen(tru } private const int TupleOfInt32AndStringId = 5; - private readonly global::System.Tuple? _tupleOfInt32AndString; + private readonly global::System.Tuple _tupleOfInt32AndString; public bool IsTupleOfInt32AndString => _variantId == TupleOfInt32AndStringId; public global::System.Tuple AsTupleOfInt32AndString { get { if (_variantId == TupleOfInt32AndStringId) - return _tupleOfInt32AndString!; + return _tupleOfInt32AndString; throw new System.InvalidOperationException("Inner value is not TupleOfInt32AndString"); } } @@ -194,11 +194,11 @@ public Result(global::System.Tuple tupleOfInt32AndString) public static explicit operator global::System.Tuple(Result value) { if (value._variantId == TupleOfInt32AndStringId) - return value._tupleOfInt32AndString!; + return value._tupleOfInt32AndString; throw new System.InvalidOperationException("Inner value is not TupleOfInt32AndString"); } - public bool TryGetTupleOfInt32AndString([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::System.Tuple? value) + public bool TryGetTupleOfInt32AndString([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::System.Tuple value) { if (_variantId == TupleOfInt32AndStringId) { @@ -215,30 +215,30 @@ public bool TryGetTupleOfInt32AndString([System.Diagnostics.CodeAnalysis.NotNull public TOut Match(global::System.Func matchSuccess, global::System.Func matchError, global::System.Func, TOut> matchIReadOnlyListOfInt32, global::System.Func matchArrayOfString, global::System.Func, TOut> matchTupleOfInt32AndString) { if (_variantId == SuccessId) - return matchSuccess(_success!); + return matchSuccess(_success); if (_variantId == ErrorId) - return matchError(_error!); + return matchError(_error); if (_variantId == IReadOnlyListOfInt32Id) - return matchIReadOnlyListOfInt32(_iReadOnlyListOfInt32!); + return matchIReadOnlyListOfInt32(_iReadOnlyListOfInt32); if (_variantId == ArrayOfStringId) - return matchArrayOfString(_arrayOfString!); + return matchArrayOfString(_arrayOfString); if (_variantId == TupleOfInt32AndStringId) - return matchTupleOfInt32AndString(_tupleOfInt32AndString!); + return matchTupleOfInt32AndString(_tupleOfInt32AndString); throw new System.InvalidOperationException("Inner type is unknown"); } public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchSuccess, global::System.Func> matchError, global::System.Func, global::System.Threading.CancellationToken, global::System.Threading.Tasks.Task> matchIReadOnlyListOfInt32, global::System.Func> matchArrayOfString, global::System.Func, global::System.Threading.CancellationToken, global::System.Threading.Tasks.Task> matchTupleOfInt32AndString, global::System.Threading.CancellationToken ct) { if (_variantId == SuccessId) - return await matchSuccess(_success!, ct).ConfigureAwait(false); + return await matchSuccess(_success, ct).ConfigureAwait(false); if (_variantId == ErrorId) - return await matchError(_error!, ct).ConfigureAwait(false); + return await matchError(_error, ct).ConfigureAwait(false); if (_variantId == IReadOnlyListOfInt32Id) - return await matchIReadOnlyListOfInt32(_iReadOnlyListOfInt32!, ct).ConfigureAwait(false); + return await matchIReadOnlyListOfInt32(_iReadOnlyListOfInt32, ct).ConfigureAwait(false); if (_variantId == ArrayOfStringId) - return await matchArrayOfString(_arrayOfString!, ct).ConfigureAwait(false); + return await matchArrayOfString(_arrayOfString, ct).ConfigureAwait(false); if (_variantId == TupleOfInt32AndStringId) - return await matchTupleOfInt32AndString(_tupleOfInt32AndString!, ct).ConfigureAwait(false); + return await matchTupleOfInt32AndString(_tupleOfInt32AndString, ct).ConfigureAwait(false); throw new System.InvalidOperationException("Inner type is unknown"); } @@ -246,31 +246,31 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - switchSuccess(_success!); + switchSuccess(_success); return; } if (_variantId == ErrorId) { - switchError(_error!); + switchError(_error); return; } if (_variantId == IReadOnlyListOfInt32Id) { - switchIReadOnlyListOfInt32(_iReadOnlyListOfInt32!); + switchIReadOnlyListOfInt32(_iReadOnlyListOfInt32); return; } if (_variantId == ArrayOfStringId) { - switchArrayOfString(_arrayOfString!); + switchArrayOfString(_arrayOfString); return; } if (_variantId == TupleOfInt32AndStringId) { - switchTupleOfInt32AndString(_tupleOfInt32AndString!); + switchTupleOfInt32AndString(_tupleOfInt32AndString); return; } @@ -281,31 +281,31 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - await switchSuccess(_success!, ct).ConfigureAwait(false); + await switchSuccess(_success, ct).ConfigureAwait(false); return; } if (_variantId == ErrorId) { - await switchError(_error!, ct).ConfigureAwait(false); + await switchError(_error, ct).ConfigureAwait(false); return; } if (_variantId == IReadOnlyListOfInt32Id) { - await switchIReadOnlyListOfInt32(_iReadOnlyListOfInt32!, ct).ConfigureAwait(false); + await switchIReadOnlyListOfInt32(_iReadOnlyListOfInt32, ct).ConfigureAwait(false); return; } if (_variantId == ArrayOfStringId) { - await switchArrayOfString(_arrayOfString!, ct).ConfigureAwait(false); + await switchArrayOfString(_arrayOfString, ct).ConfigureAwait(false); return; } if (_variantId == TupleOfInt32AndStringId) { - await switchTupleOfInt32AndString(_tupleOfInt32AndString!, ct).ConfigureAwait(false); + await switchTupleOfInt32AndString(_tupleOfInt32AndString, ct).ConfigureAwait(false); return; } @@ -363,15 +363,15 @@ public bool Equals(Result other) } if (_variantId == SuccessId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_success!, other._success); + return System.Collections.Generic.EqualityComparer.Default.Equals(_success, other._success); if (_variantId == ErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_error!, other._error); + return System.Collections.Generic.EqualityComparer.Default.Equals(_error, other._error); if (_variantId == IReadOnlyListOfInt32Id) - return System.Collections.Generic.EqualityComparer>.Default.Equals(_iReadOnlyListOfInt32!, other._iReadOnlyListOfInt32); + return System.Collections.Generic.EqualityComparer>.Default.Equals(_iReadOnlyListOfInt32, other._iReadOnlyListOfInt32); if (_variantId == ArrayOfStringId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_arrayOfString!, other._arrayOfString); + return System.Collections.Generic.EqualityComparer.Default.Equals(_arrayOfString, other._arrayOfString); if (_variantId == TupleOfInt32AndStringId) - return System.Collections.Generic.EqualityComparer>.Default.Equals(_tupleOfInt32AndString!, other._tupleOfInt32AndString); + return System.Collections.Generic.EqualityComparer>.Default.Equals(_tupleOfInt32AndString, other._tupleOfInt32AndString); throw new System.InvalidOperationException("Inner type is unknown"); } diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_partial-struct#UnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_partial-struct#UnionTypeAttribute.g.verified.cs index c9f95c1..c8f7fed 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_partial-struct#UnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_partial-struct#UnionTypeAttribute.g.verified.cs @@ -15,6 +15,7 @@ internal sealed class UnionTypeAttribute : Attribute public Type Type { get; } public string? Alias { get; } public int Order { get; } + public bool AllowNull { get; set; } public UnionTypeAttribute(Type type, string? alias = null, [CallerLineNumber] int order = 0) { diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_readonly-partial-struct#GenericUnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_readonly-partial-struct#GenericUnionTypeAttribute.g.verified.cs index 853ee82..e256764 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_readonly-partial-struct#GenericUnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_readonly-partial-struct#GenericUnionTypeAttribute.g.verified.cs @@ -9,8 +9,10 @@ namespace N.SourceGenerators.UnionTypes { - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] + [AttributeUsage(AttributeTargets.GenericParameter, Inherited = false, AllowMultiple = false)] internal sealed class GenericUnionTypeAttribute : Attribute { + public string? Alias { get; set; } + public bool AllowNull { get; set; } } } \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_readonly-partial-struct#Result.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_readonly-partial-struct#Result.g.verified.cs index 83760ac..4fa2c8a 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_readonly-partial-struct#Result.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_readonly-partial-struct#Result.g.verified.cs @@ -11,14 +11,14 @@ partial struct Result : System.IEquatable { private readonly int _variantId; private const int SuccessId = 1; - private readonly global::MyApp.Success? _success; + private readonly global::MyApp.Success _success; public bool IsSuccess => _variantId == SuccessId; public global::MyApp.Success AsSuccess { get { if (_variantId == SuccessId) - return _success!; + return _success; throw new System.InvalidOperationException("Inner value is not Success"); } } @@ -34,11 +34,11 @@ public Result(global::MyApp.Success success) public static explicit operator global::MyApp.Success(Result value) { if (value._variantId == SuccessId) - return value._success!; + return value._success; throw new System.InvalidOperationException("Inner value is not Success"); } - public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success? value) + public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success value) { if (_variantId == SuccessId) { @@ -53,14 +53,14 @@ public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] ou } private const int ErrorId = 2; - private readonly global::MyApp.Error? _error; + private readonly global::MyApp.Error _error; public bool IsError => _variantId == ErrorId; public global::MyApp.Error AsError { get { if (_variantId == ErrorId) - return _error!; + return _error; throw new System.InvalidOperationException("Inner value is not Error"); } } @@ -76,11 +76,11 @@ public Result(global::MyApp.Error @error) public static explicit operator global::MyApp.Error(Result value) { if (value._variantId == ErrorId) - return value._error!; + return value._error; throw new System.InvalidOperationException("Inner value is not Error"); } - public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Error? value) + public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Error value) { if (_variantId == ErrorId) { @@ -95,14 +95,14 @@ public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out } private const int IReadOnlyListOfInt32Id = 3; - private readonly global::System.Collections.Generic.IReadOnlyList? _iReadOnlyListOfInt32; + private readonly global::System.Collections.Generic.IReadOnlyList _iReadOnlyListOfInt32; public bool IsIReadOnlyListOfInt32 => _variantId == IReadOnlyListOfInt32Id; public global::System.Collections.Generic.IReadOnlyList AsIReadOnlyListOfInt32 { get { if (_variantId == IReadOnlyListOfInt32Id) - return _iReadOnlyListOfInt32!; + return _iReadOnlyListOfInt32; throw new System.InvalidOperationException("Inner value is not IReadOnlyListOfInt32"); } } @@ -114,7 +114,7 @@ public Result(global::System.Collections.Generic.IReadOnlyList iReadOnlyLis _iReadOnlyListOfInt32 = iReadOnlyListOfInt32; } - public bool TryGetIReadOnlyListOfInt32([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::System.Collections.Generic.IReadOnlyList? value) + public bool TryGetIReadOnlyListOfInt32([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::System.Collections.Generic.IReadOnlyList value) { if (_variantId == IReadOnlyListOfInt32Id) { @@ -129,14 +129,14 @@ public bool TryGetIReadOnlyListOfInt32([System.Diagnostics.CodeAnalysis.NotNullW } private const int ArrayOfStringId = 4; - private readonly string[]? _arrayOfString; + private readonly string[] _arrayOfString; public bool IsArrayOfString => _variantId == ArrayOfStringId; public string[] AsArrayOfString { get { if (_variantId == ArrayOfStringId) - return _arrayOfString!; + return _arrayOfString; throw new System.InvalidOperationException("Inner value is not ArrayOfString"); } } @@ -152,11 +152,11 @@ public Result(string[] arrayOfString) public static explicit operator string[](Result value) { if (value._variantId == ArrayOfStringId) - return value._arrayOfString!; + return value._arrayOfString; throw new System.InvalidOperationException("Inner value is not ArrayOfString"); } - public bool TryGetArrayOfString([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out string[]? value) + public bool TryGetArrayOfString([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out string[] value) { if (_variantId == ArrayOfStringId) { @@ -171,14 +171,14 @@ public bool TryGetArrayOfString([System.Diagnostics.CodeAnalysis.NotNullWhen(tru } private const int TupleOfInt32AndStringId = 5; - private readonly global::System.Tuple? _tupleOfInt32AndString; + private readonly global::System.Tuple _tupleOfInt32AndString; public bool IsTupleOfInt32AndString => _variantId == TupleOfInt32AndStringId; public global::System.Tuple AsTupleOfInt32AndString { get { if (_variantId == TupleOfInt32AndStringId) - return _tupleOfInt32AndString!; + return _tupleOfInt32AndString; throw new System.InvalidOperationException("Inner value is not TupleOfInt32AndString"); } } @@ -194,11 +194,11 @@ public Result(global::System.Tuple tupleOfInt32AndString) public static explicit operator global::System.Tuple(Result value) { if (value._variantId == TupleOfInt32AndStringId) - return value._tupleOfInt32AndString!; + return value._tupleOfInt32AndString; throw new System.InvalidOperationException("Inner value is not TupleOfInt32AndString"); } - public bool TryGetTupleOfInt32AndString([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::System.Tuple? value) + public bool TryGetTupleOfInt32AndString([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::System.Tuple value) { if (_variantId == TupleOfInt32AndStringId) { @@ -215,30 +215,30 @@ public bool TryGetTupleOfInt32AndString([System.Diagnostics.CodeAnalysis.NotNull public TOut Match(global::System.Func matchSuccess, global::System.Func matchError, global::System.Func, TOut> matchIReadOnlyListOfInt32, global::System.Func matchArrayOfString, global::System.Func, TOut> matchTupleOfInt32AndString) { if (_variantId == SuccessId) - return matchSuccess(_success!); + return matchSuccess(_success); if (_variantId == ErrorId) - return matchError(_error!); + return matchError(_error); if (_variantId == IReadOnlyListOfInt32Id) - return matchIReadOnlyListOfInt32(_iReadOnlyListOfInt32!); + return matchIReadOnlyListOfInt32(_iReadOnlyListOfInt32); if (_variantId == ArrayOfStringId) - return matchArrayOfString(_arrayOfString!); + return matchArrayOfString(_arrayOfString); if (_variantId == TupleOfInt32AndStringId) - return matchTupleOfInt32AndString(_tupleOfInt32AndString!); + return matchTupleOfInt32AndString(_tupleOfInt32AndString); throw new System.InvalidOperationException("Inner type is unknown"); } public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchSuccess, global::System.Func> matchError, global::System.Func, global::System.Threading.CancellationToken, global::System.Threading.Tasks.Task> matchIReadOnlyListOfInt32, global::System.Func> matchArrayOfString, global::System.Func, global::System.Threading.CancellationToken, global::System.Threading.Tasks.Task> matchTupleOfInt32AndString, global::System.Threading.CancellationToken ct) { if (_variantId == SuccessId) - return await matchSuccess(_success!, ct).ConfigureAwait(false); + return await matchSuccess(_success, ct).ConfigureAwait(false); if (_variantId == ErrorId) - return await matchError(_error!, ct).ConfigureAwait(false); + return await matchError(_error, ct).ConfigureAwait(false); if (_variantId == IReadOnlyListOfInt32Id) - return await matchIReadOnlyListOfInt32(_iReadOnlyListOfInt32!, ct).ConfigureAwait(false); + return await matchIReadOnlyListOfInt32(_iReadOnlyListOfInt32, ct).ConfigureAwait(false); if (_variantId == ArrayOfStringId) - return await matchArrayOfString(_arrayOfString!, ct).ConfigureAwait(false); + return await matchArrayOfString(_arrayOfString, ct).ConfigureAwait(false); if (_variantId == TupleOfInt32AndStringId) - return await matchTupleOfInt32AndString(_tupleOfInt32AndString!, ct).ConfigureAwait(false); + return await matchTupleOfInt32AndString(_tupleOfInt32AndString, ct).ConfigureAwait(false); throw new System.InvalidOperationException("Inner type is unknown"); } @@ -246,31 +246,31 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - switchSuccess(_success!); + switchSuccess(_success); return; } if (_variantId == ErrorId) { - switchError(_error!); + switchError(_error); return; } if (_variantId == IReadOnlyListOfInt32Id) { - switchIReadOnlyListOfInt32(_iReadOnlyListOfInt32!); + switchIReadOnlyListOfInt32(_iReadOnlyListOfInt32); return; } if (_variantId == ArrayOfStringId) { - switchArrayOfString(_arrayOfString!); + switchArrayOfString(_arrayOfString); return; } if (_variantId == TupleOfInt32AndStringId) { - switchTupleOfInt32AndString(_tupleOfInt32AndString!); + switchTupleOfInt32AndString(_tupleOfInt32AndString); return; } @@ -281,31 +281,31 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - await switchSuccess(_success!, ct).ConfigureAwait(false); + await switchSuccess(_success, ct).ConfigureAwait(false); return; } if (_variantId == ErrorId) { - await switchError(_error!, ct).ConfigureAwait(false); + await switchError(_error, ct).ConfigureAwait(false); return; } if (_variantId == IReadOnlyListOfInt32Id) { - await switchIReadOnlyListOfInt32(_iReadOnlyListOfInt32!, ct).ConfigureAwait(false); + await switchIReadOnlyListOfInt32(_iReadOnlyListOfInt32, ct).ConfigureAwait(false); return; } if (_variantId == ArrayOfStringId) { - await switchArrayOfString(_arrayOfString!, ct).ConfigureAwait(false); + await switchArrayOfString(_arrayOfString, ct).ConfigureAwait(false); return; } if (_variantId == TupleOfInt32AndStringId) { - await switchTupleOfInt32AndString(_tupleOfInt32AndString!, ct).ConfigureAwait(false); + await switchTupleOfInt32AndString(_tupleOfInt32AndString, ct).ConfigureAwait(false); return; } @@ -363,15 +363,15 @@ public bool Equals(Result other) } if (_variantId == SuccessId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_success!, other._success); + return System.Collections.Generic.EqualityComparer.Default.Equals(_success, other._success); if (_variantId == ErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_error!, other._error); + return System.Collections.Generic.EqualityComparer.Default.Equals(_error, other._error); if (_variantId == IReadOnlyListOfInt32Id) - return System.Collections.Generic.EqualityComparer>.Default.Equals(_iReadOnlyListOfInt32!, other._iReadOnlyListOfInt32); + return System.Collections.Generic.EqualityComparer>.Default.Equals(_iReadOnlyListOfInt32, other._iReadOnlyListOfInt32); if (_variantId == ArrayOfStringId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_arrayOfString!, other._arrayOfString); + return System.Collections.Generic.EqualityComparer.Default.Equals(_arrayOfString, other._arrayOfString); if (_variantId == TupleOfInt32AndStringId) - return System.Collections.Generic.EqualityComparer>.Default.Equals(_tupleOfInt32AndString!, other._tupleOfInt32AndString); + return System.Collections.Generic.EqualityComparer>.Default.Equals(_tupleOfInt32AndString, other._tupleOfInt32AndString); throw new System.InvalidOperationException("Inner type is unknown"); } diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_readonly-partial-struct#UnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_readonly-partial-struct#UnionTypeAttribute.g.verified.cs index c9f95c1..c8f7fed 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_readonly-partial-struct#UnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.DoNotOverrideToString_readonly-partial-struct#UnionTypeAttribute.g.verified.cs @@ -15,6 +15,7 @@ internal sealed class UnionTypeAttribute : Attribute public Type Type { get; } public string? Alias { get; } public int Order { get; } + public bool AllowNull { get; set; } public UnionTypeAttribute(Type type, string? alias = null, [CallerLineNumber] int order = 0) { diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.ExplicitStructLayout#GenericUnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.ExplicitStructLayout#GenericUnionTypeAttribute.g.verified.cs index 853ee82..e256764 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.ExplicitStructLayout#GenericUnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.ExplicitStructLayout#GenericUnionTypeAttribute.g.verified.cs @@ -9,8 +9,10 @@ namespace N.SourceGenerators.UnionTypes { - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] + [AttributeUsage(AttributeTargets.GenericParameter, Inherited = false, AllowMultiple = false)] internal sealed class GenericUnionTypeAttribute : Attribute { + public string? Alias { get; set; } + public bool AllowNull { get; set; } } } \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.ExplicitStructLayout#Result.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.ExplicitStructLayout#Result.g.verified.cs index 054769a..1f70898 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.ExplicitStructLayout#Result.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.ExplicitStructLayout#Result.g.verified.cs @@ -40,7 +40,7 @@ public Result(global::MyApp.SuccessStruct successStruct) throw new System.InvalidOperationException("Inner value is not SuccessStruct"); } - public bool TryGetSuccessStruct([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.SuccessStruct? value) + public bool TryGetSuccessStruct([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.SuccessStruct value) { if (_variantId == SuccessStructId) { @@ -82,7 +82,7 @@ public Result(global::MyApp.ValidationErrorStruct validationErrorStruct) throw new System.InvalidOperationException("Inner value is not ValidationErrorStruct"); } - public bool TryGetValidationErrorStruct([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.ValidationErrorStruct? value) + public bool TryGetValidationErrorStruct([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.ValidationErrorStruct value) { if (_variantId == ValidationErrorStructId) { @@ -124,7 +124,7 @@ public Result(global::MyApp.NotFoundErrorStruct notFoundErrorStruct) throw new System.InvalidOperationException("Inner value is not NotFoundErrorStruct"); } - public bool TryGetNotFoundErrorStruct([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.NotFoundErrorStruct? value) + public bool TryGetNotFoundErrorStruct([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.NotFoundErrorStruct value) { if (_variantId == NotFoundErrorStructId) { diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.ExplicitStructLayout#UnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.ExplicitStructLayout#UnionTypeAttribute.g.verified.cs index c9f95c1..c8f7fed 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.ExplicitStructLayout#UnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.ExplicitStructLayout#UnionTypeAttribute.g.verified.cs @@ -15,6 +15,7 @@ internal sealed class UnionTypeAttribute : Attribute public Type Type { get; } public string? Alias { get; } public int Order { get; } + public bool AllowNull { get; set; } public UnionTypeAttribute(Type type, string? alias = null, [CallerLineNumber] int order = 0) { diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_partial-class#GenericUnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_partial-class#GenericUnionTypeAttribute.g.verified.cs index 853ee82..e256764 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_partial-class#GenericUnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_partial-class#GenericUnionTypeAttribute.g.verified.cs @@ -9,8 +9,10 @@ namespace N.SourceGenerators.UnionTypes { - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] + [AttributeUsage(AttributeTargets.GenericParameter, Inherited = false, AllowMultiple = false)] internal sealed class GenericUnionTypeAttribute : Attribute { + public string? Alias { get; set; } + public bool AllowNull { get; set; } } } \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_partial-class#Result.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_partial-class#Result.g.verified.cs index f9d6563..5d0d17b 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_partial-class#Result.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_partial-class#Result.g.verified.cs @@ -11,14 +11,14 @@ partial class Result : System.IEquatable { private readonly int _variantId; private const int SuccessId = 1; - private readonly global::MyApp.Success? _success; + private readonly global::MyApp.Success _success; public bool IsSuccess => _variantId == SuccessId; public global::MyApp.Success AsSuccess { get { if (_variantId == SuccessId) - return _success!; + return _success; throw new System.InvalidOperationException("Inner value is not Success"); } } @@ -34,11 +34,11 @@ public Result(global::MyApp.Success success) public static explicit operator global::MyApp.Success(Result value) { if (value._variantId == SuccessId) - return value._success!; + return value._success; throw new System.InvalidOperationException("Inner value is not Success"); } - public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success? value) + public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success value) { if (_variantId == SuccessId) { @@ -53,14 +53,14 @@ public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] ou } private const int ErrorId = 2; - private readonly global::MyApp.Error? _error; + private readonly global::MyApp.Error _error; public bool IsError => _variantId == ErrorId; public global::MyApp.Error AsError { get { if (_variantId == ErrorId) - return _error!; + return _error; throw new System.InvalidOperationException("Inner value is not Error"); } } @@ -76,11 +76,11 @@ public Result(global::MyApp.Error @error) public static explicit operator global::MyApp.Error(Result value) { if (value._variantId == ErrorId) - return value._error!; + return value._error; throw new System.InvalidOperationException("Inner value is not Error"); } - public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Error? value) + public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Error value) { if (_variantId == ErrorId) { @@ -95,14 +95,14 @@ public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out } private const int IReadOnlyListOfInt32Id = 3; - private readonly global::System.Collections.Generic.IReadOnlyList? _iReadOnlyListOfInt32; + private readonly global::System.Collections.Generic.IReadOnlyList _iReadOnlyListOfInt32; public bool IsIReadOnlyListOfInt32 => _variantId == IReadOnlyListOfInt32Id; public global::System.Collections.Generic.IReadOnlyList AsIReadOnlyListOfInt32 { get { if (_variantId == IReadOnlyListOfInt32Id) - return _iReadOnlyListOfInt32!; + return _iReadOnlyListOfInt32; throw new System.InvalidOperationException("Inner value is not IReadOnlyListOfInt32"); } } @@ -114,7 +114,7 @@ public Result(global::System.Collections.Generic.IReadOnlyList iReadOnlyLis _iReadOnlyListOfInt32 = iReadOnlyListOfInt32; } - public bool TryGetIReadOnlyListOfInt32([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::System.Collections.Generic.IReadOnlyList? value) + public bool TryGetIReadOnlyListOfInt32([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::System.Collections.Generic.IReadOnlyList value) { if (_variantId == IReadOnlyListOfInt32Id) { @@ -129,14 +129,14 @@ public bool TryGetIReadOnlyListOfInt32([System.Diagnostics.CodeAnalysis.NotNullW } private const int ArrayOfStringId = 4; - private readonly string[]? _arrayOfString; + private readonly string[] _arrayOfString; public bool IsArrayOfString => _variantId == ArrayOfStringId; public string[] AsArrayOfString { get { if (_variantId == ArrayOfStringId) - return _arrayOfString!; + return _arrayOfString; throw new System.InvalidOperationException("Inner value is not ArrayOfString"); } } @@ -152,11 +152,11 @@ public Result(string[] arrayOfString) public static explicit operator string[](Result value) { if (value._variantId == ArrayOfStringId) - return value._arrayOfString!; + return value._arrayOfString; throw new System.InvalidOperationException("Inner value is not ArrayOfString"); } - public bool TryGetArrayOfString([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out string[]? value) + public bool TryGetArrayOfString([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out string[] value) { if (_variantId == ArrayOfStringId) { @@ -171,14 +171,14 @@ public bool TryGetArrayOfString([System.Diagnostics.CodeAnalysis.NotNullWhen(tru } private const int TupleOfInt32AndStringId = 5; - private readonly global::System.Tuple? _tupleOfInt32AndString; + private readonly global::System.Tuple _tupleOfInt32AndString; public bool IsTupleOfInt32AndString => _variantId == TupleOfInt32AndStringId; public global::System.Tuple AsTupleOfInt32AndString { get { if (_variantId == TupleOfInt32AndStringId) - return _tupleOfInt32AndString!; + return _tupleOfInt32AndString; throw new System.InvalidOperationException("Inner value is not TupleOfInt32AndString"); } } @@ -194,11 +194,11 @@ public Result(global::System.Tuple tupleOfInt32AndString) public static explicit operator global::System.Tuple(Result value) { if (value._variantId == TupleOfInt32AndStringId) - return value._tupleOfInt32AndString!; + return value._tupleOfInt32AndString; throw new System.InvalidOperationException("Inner value is not TupleOfInt32AndString"); } - public bool TryGetTupleOfInt32AndString([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::System.Tuple? value) + public bool TryGetTupleOfInt32AndString([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::System.Tuple value) { if (_variantId == TupleOfInt32AndStringId) { @@ -215,30 +215,30 @@ public bool TryGetTupleOfInt32AndString([System.Diagnostics.CodeAnalysis.NotNull public TOut Match(global::System.Func matchSuccess, global::System.Func matchError, global::System.Func, TOut> matchIReadOnlyListOfInt32, global::System.Func matchArrayOfString, global::System.Func, TOut> matchTupleOfInt32AndString) { if (_variantId == SuccessId) - return matchSuccess(_success!); + return matchSuccess(_success); if (_variantId == ErrorId) - return matchError(_error!); + return matchError(_error); if (_variantId == IReadOnlyListOfInt32Id) - return matchIReadOnlyListOfInt32(_iReadOnlyListOfInt32!); + return matchIReadOnlyListOfInt32(_iReadOnlyListOfInt32); if (_variantId == ArrayOfStringId) - return matchArrayOfString(_arrayOfString!); + return matchArrayOfString(_arrayOfString); if (_variantId == TupleOfInt32AndStringId) - return matchTupleOfInt32AndString(_tupleOfInt32AndString!); + return matchTupleOfInt32AndString(_tupleOfInt32AndString); throw new System.InvalidOperationException("Inner type is unknown"); } public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchSuccess, global::System.Func> matchError, global::System.Func, global::System.Threading.CancellationToken, global::System.Threading.Tasks.Task> matchIReadOnlyListOfInt32, global::System.Func> matchArrayOfString, global::System.Func, global::System.Threading.CancellationToken, global::System.Threading.Tasks.Task> matchTupleOfInt32AndString, global::System.Threading.CancellationToken ct) { if (_variantId == SuccessId) - return await matchSuccess(_success!, ct).ConfigureAwait(false); + return await matchSuccess(_success, ct).ConfigureAwait(false); if (_variantId == ErrorId) - return await matchError(_error!, ct).ConfigureAwait(false); + return await matchError(_error, ct).ConfigureAwait(false); if (_variantId == IReadOnlyListOfInt32Id) - return await matchIReadOnlyListOfInt32(_iReadOnlyListOfInt32!, ct).ConfigureAwait(false); + return await matchIReadOnlyListOfInt32(_iReadOnlyListOfInt32, ct).ConfigureAwait(false); if (_variantId == ArrayOfStringId) - return await matchArrayOfString(_arrayOfString!, ct).ConfigureAwait(false); + return await matchArrayOfString(_arrayOfString, ct).ConfigureAwait(false); if (_variantId == TupleOfInt32AndStringId) - return await matchTupleOfInt32AndString(_tupleOfInt32AndString!, ct).ConfigureAwait(false); + return await matchTupleOfInt32AndString(_tupleOfInt32AndString, ct).ConfigureAwait(false); throw new System.InvalidOperationException("Inner type is unknown"); } @@ -246,31 +246,31 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - switchSuccess(_success!); + switchSuccess(_success); return; } if (_variantId == ErrorId) { - switchError(_error!); + switchError(_error); return; } if (_variantId == IReadOnlyListOfInt32Id) { - switchIReadOnlyListOfInt32(_iReadOnlyListOfInt32!); + switchIReadOnlyListOfInt32(_iReadOnlyListOfInt32); return; } if (_variantId == ArrayOfStringId) { - switchArrayOfString(_arrayOfString!); + switchArrayOfString(_arrayOfString); return; } if (_variantId == TupleOfInt32AndStringId) { - switchTupleOfInt32AndString(_tupleOfInt32AndString!); + switchTupleOfInt32AndString(_tupleOfInt32AndString); return; } @@ -281,31 +281,31 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - await switchSuccess(_success!, ct).ConfigureAwait(false); + await switchSuccess(_success, ct).ConfigureAwait(false); return; } if (_variantId == ErrorId) { - await switchError(_error!, ct).ConfigureAwait(false); + await switchError(_error, ct).ConfigureAwait(false); return; } if (_variantId == IReadOnlyListOfInt32Id) { - await switchIReadOnlyListOfInt32(_iReadOnlyListOfInt32!, ct).ConfigureAwait(false); + await switchIReadOnlyListOfInt32(_iReadOnlyListOfInt32, ct).ConfigureAwait(false); return; } if (_variantId == ArrayOfStringId) { - await switchArrayOfString(_arrayOfString!, ct).ConfigureAwait(false); + await switchArrayOfString(_arrayOfString, ct).ConfigureAwait(false); return; } if (_variantId == TupleOfInt32AndStringId) { - await switchTupleOfInt32AndString(_tupleOfInt32AndString!, ct).ConfigureAwait(false); + await switchTupleOfInt32AndString(_tupleOfInt32AndString, ct).ConfigureAwait(false); return; } @@ -373,15 +373,15 @@ public bool Equals(Result? other) } if (_variantId == SuccessId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_success!, other._success); + return System.Collections.Generic.EqualityComparer.Default.Equals(_success, other._success); if (_variantId == ErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_error!, other._error); + return System.Collections.Generic.EqualityComparer.Default.Equals(_error, other._error); if (_variantId == IReadOnlyListOfInt32Id) - return System.Collections.Generic.EqualityComparer>.Default.Equals(_iReadOnlyListOfInt32!, other._iReadOnlyListOfInt32); + return System.Collections.Generic.EqualityComparer>.Default.Equals(_iReadOnlyListOfInt32, other._iReadOnlyListOfInt32); if (_variantId == ArrayOfStringId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_arrayOfString!, other._arrayOfString); + return System.Collections.Generic.EqualityComparer.Default.Equals(_arrayOfString, other._arrayOfString); if (_variantId == TupleOfInt32AndStringId) - return System.Collections.Generic.EqualityComparer>.Default.Equals(_tupleOfInt32AndString!, other._tupleOfInt32AndString); + return System.Collections.Generic.EqualityComparer>.Default.Equals(_tupleOfInt32AndString, other._tupleOfInt32AndString); throw new System.InvalidOperationException("Inner type is unknown"); } diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_partial-class#UnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_partial-class#UnionTypeAttribute.g.verified.cs index c9f95c1..c8f7fed 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_partial-class#UnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_partial-class#UnionTypeAttribute.g.verified.cs @@ -15,6 +15,7 @@ internal sealed class UnionTypeAttribute : Attribute public Type Type { get; } public string? Alias { get; } public int Order { get; } + public bool AllowNull { get; set; } public UnionTypeAttribute(Type type, string? alias = null, [CallerLineNumber] int order = 0) { diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_partial-struct#GenericUnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_partial-struct#GenericUnionTypeAttribute.g.verified.cs index 853ee82..e256764 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_partial-struct#GenericUnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_partial-struct#GenericUnionTypeAttribute.g.verified.cs @@ -9,8 +9,10 @@ namespace N.SourceGenerators.UnionTypes { - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] + [AttributeUsage(AttributeTargets.GenericParameter, Inherited = false, AllowMultiple = false)] internal sealed class GenericUnionTypeAttribute : Attribute { + public string? Alias { get; set; } + public bool AllowNull { get; set; } } } \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_partial-struct#Result.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_partial-struct#Result.g.verified.cs index b1a96d0..f719670 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_partial-struct#Result.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_partial-struct#Result.g.verified.cs @@ -11,14 +11,14 @@ partial struct Result : System.IEquatable { private readonly int _variantId; private const int SuccessId = 1; - private readonly global::MyApp.Success? _success; + private readonly global::MyApp.Success _success; public bool IsSuccess => _variantId == SuccessId; public global::MyApp.Success AsSuccess { get { if (_variantId == SuccessId) - return _success!; + return _success; throw new System.InvalidOperationException("Inner value is not Success"); } } @@ -34,11 +34,11 @@ public Result(global::MyApp.Success success) public static explicit operator global::MyApp.Success(Result value) { if (value._variantId == SuccessId) - return value._success!; + return value._success; throw new System.InvalidOperationException("Inner value is not Success"); } - public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success? value) + public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success value) { if (_variantId == SuccessId) { @@ -53,14 +53,14 @@ public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] ou } private const int ErrorId = 2; - private readonly global::MyApp.Error? _error; + private readonly global::MyApp.Error _error; public bool IsError => _variantId == ErrorId; public global::MyApp.Error AsError { get { if (_variantId == ErrorId) - return _error!; + return _error; throw new System.InvalidOperationException("Inner value is not Error"); } } @@ -76,11 +76,11 @@ public Result(global::MyApp.Error @error) public static explicit operator global::MyApp.Error(Result value) { if (value._variantId == ErrorId) - return value._error!; + return value._error; throw new System.InvalidOperationException("Inner value is not Error"); } - public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Error? value) + public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Error value) { if (_variantId == ErrorId) { @@ -95,14 +95,14 @@ public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out } private const int IReadOnlyListOfInt32Id = 3; - private readonly global::System.Collections.Generic.IReadOnlyList? _iReadOnlyListOfInt32; + private readonly global::System.Collections.Generic.IReadOnlyList _iReadOnlyListOfInt32; public bool IsIReadOnlyListOfInt32 => _variantId == IReadOnlyListOfInt32Id; public global::System.Collections.Generic.IReadOnlyList AsIReadOnlyListOfInt32 { get { if (_variantId == IReadOnlyListOfInt32Id) - return _iReadOnlyListOfInt32!; + return _iReadOnlyListOfInt32; throw new System.InvalidOperationException("Inner value is not IReadOnlyListOfInt32"); } } @@ -114,7 +114,7 @@ public Result(global::System.Collections.Generic.IReadOnlyList iReadOnlyLis _iReadOnlyListOfInt32 = iReadOnlyListOfInt32; } - public bool TryGetIReadOnlyListOfInt32([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::System.Collections.Generic.IReadOnlyList? value) + public bool TryGetIReadOnlyListOfInt32([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::System.Collections.Generic.IReadOnlyList value) { if (_variantId == IReadOnlyListOfInt32Id) { @@ -129,14 +129,14 @@ public bool TryGetIReadOnlyListOfInt32([System.Diagnostics.CodeAnalysis.NotNullW } private const int ArrayOfStringId = 4; - private readonly string[]? _arrayOfString; + private readonly string[] _arrayOfString; public bool IsArrayOfString => _variantId == ArrayOfStringId; public string[] AsArrayOfString { get { if (_variantId == ArrayOfStringId) - return _arrayOfString!; + return _arrayOfString; throw new System.InvalidOperationException("Inner value is not ArrayOfString"); } } @@ -152,11 +152,11 @@ public Result(string[] arrayOfString) public static explicit operator string[](Result value) { if (value._variantId == ArrayOfStringId) - return value._arrayOfString!; + return value._arrayOfString; throw new System.InvalidOperationException("Inner value is not ArrayOfString"); } - public bool TryGetArrayOfString([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out string[]? value) + public bool TryGetArrayOfString([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out string[] value) { if (_variantId == ArrayOfStringId) { @@ -171,14 +171,14 @@ public bool TryGetArrayOfString([System.Diagnostics.CodeAnalysis.NotNullWhen(tru } private const int TupleOfInt32AndStringId = 5; - private readonly global::System.Tuple? _tupleOfInt32AndString; + private readonly global::System.Tuple _tupleOfInt32AndString; public bool IsTupleOfInt32AndString => _variantId == TupleOfInt32AndStringId; public global::System.Tuple AsTupleOfInt32AndString { get { if (_variantId == TupleOfInt32AndStringId) - return _tupleOfInt32AndString!; + return _tupleOfInt32AndString; throw new System.InvalidOperationException("Inner value is not TupleOfInt32AndString"); } } @@ -194,11 +194,11 @@ public Result(global::System.Tuple tupleOfInt32AndString) public static explicit operator global::System.Tuple(Result value) { if (value._variantId == TupleOfInt32AndStringId) - return value._tupleOfInt32AndString!; + return value._tupleOfInt32AndString; throw new System.InvalidOperationException("Inner value is not TupleOfInt32AndString"); } - public bool TryGetTupleOfInt32AndString([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::System.Tuple? value) + public bool TryGetTupleOfInt32AndString([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::System.Tuple value) { if (_variantId == TupleOfInt32AndStringId) { @@ -215,30 +215,30 @@ public bool TryGetTupleOfInt32AndString([System.Diagnostics.CodeAnalysis.NotNull public TOut Match(global::System.Func matchSuccess, global::System.Func matchError, global::System.Func, TOut> matchIReadOnlyListOfInt32, global::System.Func matchArrayOfString, global::System.Func, TOut> matchTupleOfInt32AndString) { if (_variantId == SuccessId) - return matchSuccess(_success!); + return matchSuccess(_success); if (_variantId == ErrorId) - return matchError(_error!); + return matchError(_error); if (_variantId == IReadOnlyListOfInt32Id) - return matchIReadOnlyListOfInt32(_iReadOnlyListOfInt32!); + return matchIReadOnlyListOfInt32(_iReadOnlyListOfInt32); if (_variantId == ArrayOfStringId) - return matchArrayOfString(_arrayOfString!); + return matchArrayOfString(_arrayOfString); if (_variantId == TupleOfInt32AndStringId) - return matchTupleOfInt32AndString(_tupleOfInt32AndString!); + return matchTupleOfInt32AndString(_tupleOfInt32AndString); throw new System.InvalidOperationException("Inner type is unknown"); } public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchSuccess, global::System.Func> matchError, global::System.Func, global::System.Threading.CancellationToken, global::System.Threading.Tasks.Task> matchIReadOnlyListOfInt32, global::System.Func> matchArrayOfString, global::System.Func, global::System.Threading.CancellationToken, global::System.Threading.Tasks.Task> matchTupleOfInt32AndString, global::System.Threading.CancellationToken ct) { if (_variantId == SuccessId) - return await matchSuccess(_success!, ct).ConfigureAwait(false); + return await matchSuccess(_success, ct).ConfigureAwait(false); if (_variantId == ErrorId) - return await matchError(_error!, ct).ConfigureAwait(false); + return await matchError(_error, ct).ConfigureAwait(false); if (_variantId == IReadOnlyListOfInt32Id) - return await matchIReadOnlyListOfInt32(_iReadOnlyListOfInt32!, ct).ConfigureAwait(false); + return await matchIReadOnlyListOfInt32(_iReadOnlyListOfInt32, ct).ConfigureAwait(false); if (_variantId == ArrayOfStringId) - return await matchArrayOfString(_arrayOfString!, ct).ConfigureAwait(false); + return await matchArrayOfString(_arrayOfString, ct).ConfigureAwait(false); if (_variantId == TupleOfInt32AndStringId) - return await matchTupleOfInt32AndString(_tupleOfInt32AndString!, ct).ConfigureAwait(false); + return await matchTupleOfInt32AndString(_tupleOfInt32AndString, ct).ConfigureAwait(false); throw new System.InvalidOperationException("Inner type is unknown"); } @@ -246,31 +246,31 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - switchSuccess(_success!); + switchSuccess(_success); return; } if (_variantId == ErrorId) { - switchError(_error!); + switchError(_error); return; } if (_variantId == IReadOnlyListOfInt32Id) { - switchIReadOnlyListOfInt32(_iReadOnlyListOfInt32!); + switchIReadOnlyListOfInt32(_iReadOnlyListOfInt32); return; } if (_variantId == ArrayOfStringId) { - switchArrayOfString(_arrayOfString!); + switchArrayOfString(_arrayOfString); return; } if (_variantId == TupleOfInt32AndStringId) { - switchTupleOfInt32AndString(_tupleOfInt32AndString!); + switchTupleOfInt32AndString(_tupleOfInt32AndString); return; } @@ -281,31 +281,31 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - await switchSuccess(_success!, ct).ConfigureAwait(false); + await switchSuccess(_success, ct).ConfigureAwait(false); return; } if (_variantId == ErrorId) { - await switchError(_error!, ct).ConfigureAwait(false); + await switchError(_error, ct).ConfigureAwait(false); return; } if (_variantId == IReadOnlyListOfInt32Id) { - await switchIReadOnlyListOfInt32(_iReadOnlyListOfInt32!, ct).ConfigureAwait(false); + await switchIReadOnlyListOfInt32(_iReadOnlyListOfInt32, ct).ConfigureAwait(false); return; } if (_variantId == ArrayOfStringId) { - await switchArrayOfString(_arrayOfString!, ct).ConfigureAwait(false); + await switchArrayOfString(_arrayOfString, ct).ConfigureAwait(false); return; } if (_variantId == TupleOfInt32AndStringId) { - await switchTupleOfInt32AndString(_tupleOfInt32AndString!, ct).ConfigureAwait(false); + await switchTupleOfInt32AndString(_tupleOfInt32AndString, ct).ConfigureAwait(false); return; } @@ -363,15 +363,15 @@ public bool Equals(Result other) } if (_variantId == SuccessId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_success!, other._success); + return System.Collections.Generic.EqualityComparer.Default.Equals(_success, other._success); if (_variantId == ErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_error!, other._error); + return System.Collections.Generic.EqualityComparer.Default.Equals(_error, other._error); if (_variantId == IReadOnlyListOfInt32Id) - return System.Collections.Generic.EqualityComparer>.Default.Equals(_iReadOnlyListOfInt32!, other._iReadOnlyListOfInt32); + return System.Collections.Generic.EqualityComparer>.Default.Equals(_iReadOnlyListOfInt32, other._iReadOnlyListOfInt32); if (_variantId == ArrayOfStringId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_arrayOfString!, other._arrayOfString); + return System.Collections.Generic.EqualityComparer.Default.Equals(_arrayOfString, other._arrayOfString); if (_variantId == TupleOfInt32AndStringId) - return System.Collections.Generic.EqualityComparer>.Default.Equals(_tupleOfInt32AndString!, other._tupleOfInt32AndString); + return System.Collections.Generic.EqualityComparer>.Default.Equals(_tupleOfInt32AndString, other._tupleOfInt32AndString); throw new System.InvalidOperationException("Inner type is unknown"); } diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_partial-struct#UnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_partial-struct#UnionTypeAttribute.g.verified.cs index c9f95c1..c8f7fed 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_partial-struct#UnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_partial-struct#UnionTypeAttribute.g.verified.cs @@ -15,6 +15,7 @@ internal sealed class UnionTypeAttribute : Attribute public Type Type { get; } public string? Alias { get; } public int Order { get; } + public bool AllowNull { get; set; } public UnionTypeAttribute(Type type, string? alias = null, [CallerLineNumber] int order = 0) { diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_readonly-partial-struct#GenericUnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_readonly-partial-struct#GenericUnionTypeAttribute.g.verified.cs index 853ee82..e256764 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_readonly-partial-struct#GenericUnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_readonly-partial-struct#GenericUnionTypeAttribute.g.verified.cs @@ -9,8 +9,10 @@ namespace N.SourceGenerators.UnionTypes { - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] + [AttributeUsage(AttributeTargets.GenericParameter, Inherited = false, AllowMultiple = false)] internal sealed class GenericUnionTypeAttribute : Attribute { + public string? Alias { get; set; } + public bool AllowNull { get; set; } } } \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_readonly-partial-struct#Result.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_readonly-partial-struct#Result.g.verified.cs index b1a96d0..f719670 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_readonly-partial-struct#Result.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_readonly-partial-struct#Result.g.verified.cs @@ -11,14 +11,14 @@ partial struct Result : System.IEquatable { private readonly int _variantId; private const int SuccessId = 1; - private readonly global::MyApp.Success? _success; + private readonly global::MyApp.Success _success; public bool IsSuccess => _variantId == SuccessId; public global::MyApp.Success AsSuccess { get { if (_variantId == SuccessId) - return _success!; + return _success; throw new System.InvalidOperationException("Inner value is not Success"); } } @@ -34,11 +34,11 @@ public Result(global::MyApp.Success success) public static explicit operator global::MyApp.Success(Result value) { if (value._variantId == SuccessId) - return value._success!; + return value._success; throw new System.InvalidOperationException("Inner value is not Success"); } - public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success? value) + public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Success value) { if (_variantId == SuccessId) { @@ -53,14 +53,14 @@ public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] ou } private const int ErrorId = 2; - private readonly global::MyApp.Error? _error; + private readonly global::MyApp.Error _error; public bool IsError => _variantId == ErrorId; public global::MyApp.Error AsError { get { if (_variantId == ErrorId) - return _error!; + return _error; throw new System.InvalidOperationException("Inner value is not Error"); } } @@ -76,11 +76,11 @@ public Result(global::MyApp.Error @error) public static explicit operator global::MyApp.Error(Result value) { if (value._variantId == ErrorId) - return value._error!; + return value._error; throw new System.InvalidOperationException("Inner value is not Error"); } - public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Error? value) + public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::MyApp.Error value) { if (_variantId == ErrorId) { @@ -95,14 +95,14 @@ public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out } private const int IReadOnlyListOfInt32Id = 3; - private readonly global::System.Collections.Generic.IReadOnlyList? _iReadOnlyListOfInt32; + private readonly global::System.Collections.Generic.IReadOnlyList _iReadOnlyListOfInt32; public bool IsIReadOnlyListOfInt32 => _variantId == IReadOnlyListOfInt32Id; public global::System.Collections.Generic.IReadOnlyList AsIReadOnlyListOfInt32 { get { if (_variantId == IReadOnlyListOfInt32Id) - return _iReadOnlyListOfInt32!; + return _iReadOnlyListOfInt32; throw new System.InvalidOperationException("Inner value is not IReadOnlyListOfInt32"); } } @@ -114,7 +114,7 @@ public Result(global::System.Collections.Generic.IReadOnlyList iReadOnlyLis _iReadOnlyListOfInt32 = iReadOnlyListOfInt32; } - public bool TryGetIReadOnlyListOfInt32([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::System.Collections.Generic.IReadOnlyList? value) + public bool TryGetIReadOnlyListOfInt32([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::System.Collections.Generic.IReadOnlyList value) { if (_variantId == IReadOnlyListOfInt32Id) { @@ -129,14 +129,14 @@ public bool TryGetIReadOnlyListOfInt32([System.Diagnostics.CodeAnalysis.NotNullW } private const int ArrayOfStringId = 4; - private readonly string[]? _arrayOfString; + private readonly string[] _arrayOfString; public bool IsArrayOfString => _variantId == ArrayOfStringId; public string[] AsArrayOfString { get { if (_variantId == ArrayOfStringId) - return _arrayOfString!; + return _arrayOfString; throw new System.InvalidOperationException("Inner value is not ArrayOfString"); } } @@ -152,11 +152,11 @@ public Result(string[] arrayOfString) public static explicit operator string[](Result value) { if (value._variantId == ArrayOfStringId) - return value._arrayOfString!; + return value._arrayOfString; throw new System.InvalidOperationException("Inner value is not ArrayOfString"); } - public bool TryGetArrayOfString([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out string[]? value) + public bool TryGetArrayOfString([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out string[] value) { if (_variantId == ArrayOfStringId) { @@ -171,14 +171,14 @@ public bool TryGetArrayOfString([System.Diagnostics.CodeAnalysis.NotNullWhen(tru } private const int TupleOfInt32AndStringId = 5; - private readonly global::System.Tuple? _tupleOfInt32AndString; + private readonly global::System.Tuple _tupleOfInt32AndString; public bool IsTupleOfInt32AndString => _variantId == TupleOfInt32AndStringId; public global::System.Tuple AsTupleOfInt32AndString { get { if (_variantId == TupleOfInt32AndStringId) - return _tupleOfInt32AndString!; + return _tupleOfInt32AndString; throw new System.InvalidOperationException("Inner value is not TupleOfInt32AndString"); } } @@ -194,11 +194,11 @@ public Result(global::System.Tuple tupleOfInt32AndString) public static explicit operator global::System.Tuple(Result value) { if (value._variantId == TupleOfInt32AndStringId) - return value._tupleOfInt32AndString!; + return value._tupleOfInt32AndString; throw new System.InvalidOperationException("Inner value is not TupleOfInt32AndString"); } - public bool TryGetTupleOfInt32AndString([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::System.Tuple? value) + public bool TryGetTupleOfInt32AndString([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::System.Tuple value) { if (_variantId == TupleOfInt32AndStringId) { @@ -215,30 +215,30 @@ public bool TryGetTupleOfInt32AndString([System.Diagnostics.CodeAnalysis.NotNull public TOut Match(global::System.Func matchSuccess, global::System.Func matchError, global::System.Func, TOut> matchIReadOnlyListOfInt32, global::System.Func matchArrayOfString, global::System.Func, TOut> matchTupleOfInt32AndString) { if (_variantId == SuccessId) - return matchSuccess(_success!); + return matchSuccess(_success); if (_variantId == ErrorId) - return matchError(_error!); + return matchError(_error); if (_variantId == IReadOnlyListOfInt32Id) - return matchIReadOnlyListOfInt32(_iReadOnlyListOfInt32!); + return matchIReadOnlyListOfInt32(_iReadOnlyListOfInt32); if (_variantId == ArrayOfStringId) - return matchArrayOfString(_arrayOfString!); + return matchArrayOfString(_arrayOfString); if (_variantId == TupleOfInt32AndStringId) - return matchTupleOfInt32AndString(_tupleOfInt32AndString!); + return matchTupleOfInt32AndString(_tupleOfInt32AndString); throw new System.InvalidOperationException("Inner type is unknown"); } public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchSuccess, global::System.Func> matchError, global::System.Func, global::System.Threading.CancellationToken, global::System.Threading.Tasks.Task> matchIReadOnlyListOfInt32, global::System.Func> matchArrayOfString, global::System.Func, global::System.Threading.CancellationToken, global::System.Threading.Tasks.Task> matchTupleOfInt32AndString, global::System.Threading.CancellationToken ct) { if (_variantId == SuccessId) - return await matchSuccess(_success!, ct).ConfigureAwait(false); + return await matchSuccess(_success, ct).ConfigureAwait(false); if (_variantId == ErrorId) - return await matchError(_error!, ct).ConfigureAwait(false); + return await matchError(_error, ct).ConfigureAwait(false); if (_variantId == IReadOnlyListOfInt32Id) - return await matchIReadOnlyListOfInt32(_iReadOnlyListOfInt32!, ct).ConfigureAwait(false); + return await matchIReadOnlyListOfInt32(_iReadOnlyListOfInt32, ct).ConfigureAwait(false); if (_variantId == ArrayOfStringId) - return await matchArrayOfString(_arrayOfString!, ct).ConfigureAwait(false); + return await matchArrayOfString(_arrayOfString, ct).ConfigureAwait(false); if (_variantId == TupleOfInt32AndStringId) - return await matchTupleOfInt32AndString(_tupleOfInt32AndString!, ct).ConfigureAwait(false); + return await matchTupleOfInt32AndString(_tupleOfInt32AndString, ct).ConfigureAwait(false); throw new System.InvalidOperationException("Inner type is unknown"); } @@ -246,31 +246,31 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - switchSuccess(_success!); + switchSuccess(_success); return; } if (_variantId == ErrorId) { - switchError(_error!); + switchError(_error); return; } if (_variantId == IReadOnlyListOfInt32Id) { - switchIReadOnlyListOfInt32(_iReadOnlyListOfInt32!); + switchIReadOnlyListOfInt32(_iReadOnlyListOfInt32); return; } if (_variantId == ArrayOfStringId) { - switchArrayOfString(_arrayOfString!); + switchArrayOfString(_arrayOfString); return; } if (_variantId == TupleOfInt32AndStringId) { - switchTupleOfInt32AndString(_tupleOfInt32AndString!); + switchTupleOfInt32AndString(_tupleOfInt32AndString); return; } @@ -281,31 +281,31 @@ public void Switch(global::System.Action switchSuccess, g { if (_variantId == SuccessId) { - await switchSuccess(_success!, ct).ConfigureAwait(false); + await switchSuccess(_success, ct).ConfigureAwait(false); return; } if (_variantId == ErrorId) { - await switchError(_error!, ct).ConfigureAwait(false); + await switchError(_error, ct).ConfigureAwait(false); return; } if (_variantId == IReadOnlyListOfInt32Id) { - await switchIReadOnlyListOfInt32(_iReadOnlyListOfInt32!, ct).ConfigureAwait(false); + await switchIReadOnlyListOfInt32(_iReadOnlyListOfInt32, ct).ConfigureAwait(false); return; } if (_variantId == ArrayOfStringId) { - await switchArrayOfString(_arrayOfString!, ct).ConfigureAwait(false); + await switchArrayOfString(_arrayOfString, ct).ConfigureAwait(false); return; } if (_variantId == TupleOfInt32AndStringId) { - await switchTupleOfInt32AndString(_tupleOfInt32AndString!, ct).ConfigureAwait(false); + await switchTupleOfInt32AndString(_tupleOfInt32AndString, ct).ConfigureAwait(false); return; } @@ -363,15 +363,15 @@ public bool Equals(Result other) } if (_variantId == SuccessId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_success!, other._success); + return System.Collections.Generic.EqualityComparer.Default.Equals(_success, other._success); if (_variantId == ErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_error!, other._error); + return System.Collections.Generic.EqualityComparer.Default.Equals(_error, other._error); if (_variantId == IReadOnlyListOfInt32Id) - return System.Collections.Generic.EqualityComparer>.Default.Equals(_iReadOnlyListOfInt32!, other._iReadOnlyListOfInt32); + return System.Collections.Generic.EqualityComparer>.Default.Equals(_iReadOnlyListOfInt32, other._iReadOnlyListOfInt32); if (_variantId == ArrayOfStringId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_arrayOfString!, other._arrayOfString); + return System.Collections.Generic.EqualityComparer.Default.Equals(_arrayOfString, other._arrayOfString); if (_variantId == TupleOfInt32AndStringId) - return System.Collections.Generic.EqualityComparer>.Default.Equals(_tupleOfInt32AndString!, other._tupleOfInt32AndString); + return System.Collections.Generic.EqualityComparer>.Default.Equals(_tupleOfInt32AndString, other._tupleOfInt32AndString); throw new System.InvalidOperationException("Inner type is unknown"); } diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_readonly-partial-struct#UnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_readonly-partial-struct#UnionTypeAttribute.g.verified.cs index c9f95c1..c8f7fed 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_readonly-partial-struct#UnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithNamespace_readonly-partial-struct#UnionTypeAttribute.g.verified.cs @@ -15,6 +15,7 @@ internal sealed class UnionTypeAttribute : Attribute public Type Type { get; } public string? Alias { get; } public int Order { get; } + public bool AllowNull { get; set; } public UnionTypeAttribute(Type type, string? alias = null, [CallerLineNumber] int order = 0) { diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_partial-class#GenericUnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_partial-class#GenericUnionTypeAttribute.g.verified.cs index 853ee82..e256764 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_partial-class#GenericUnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_partial-class#GenericUnionTypeAttribute.g.verified.cs @@ -9,8 +9,10 @@ namespace N.SourceGenerators.UnionTypes { - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] + [AttributeUsage(AttributeTargets.GenericParameter, Inherited = false, AllowMultiple = false)] internal sealed class GenericUnionTypeAttribute : Attribute { + public string? Alias { get; set; } + public bool AllowNull { get; set; } } } \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_partial-class#Result.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_partial-class#Result.g.verified.cs index 09819f6..c15656e 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_partial-class#Result.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_partial-class#Result.g.verified.cs @@ -9,14 +9,14 @@ partial class Result : System.IEquatable { private readonly int _variantId; private const int SuccessId = 1; - private readonly global::Success? _success; + private readonly global::Success _success; public bool IsSuccess => _variantId == SuccessId; public global::Success AsSuccess { get { if (_variantId == SuccessId) - return _success!; + return _success; throw new System.InvalidOperationException("Inner value is not Success"); } } @@ -32,11 +32,11 @@ public Result(global::Success success) public static explicit operator global::Success(Result value) { if (value._variantId == SuccessId) - return value._success!; + return value._success; throw new System.InvalidOperationException("Inner value is not Success"); } - public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Success? value) + public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Success value) { if (_variantId == SuccessId) { @@ -51,14 +51,14 @@ public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] ou } private const int ErrorId = 2; - private readonly global::Error? _error; + private readonly global::Error _error; public bool IsError => _variantId == ErrorId; public global::Error AsError { get { if (_variantId == ErrorId) - return _error!; + return _error; throw new System.InvalidOperationException("Inner value is not Error"); } } @@ -74,11 +74,11 @@ public Result(global::Error @error) public static explicit operator global::Error(Result value) { if (value._variantId == ErrorId) - return value._error!; + return value._error; throw new System.InvalidOperationException("Inner value is not Error"); } - public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Error? value) + public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Error value) { if (_variantId == ErrorId) { @@ -93,14 +93,14 @@ public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out } private const int WrappedOfIReadOnlyListOfStringId = 3; - private readonly global::Wrapped>? _wrappedOfIReadOnlyListOfString; + private readonly global::Wrapped> _wrappedOfIReadOnlyListOfString; public bool IsWrappedOfIReadOnlyListOfString => _variantId == WrappedOfIReadOnlyListOfStringId; public global::Wrapped> AsWrappedOfIReadOnlyListOfString { get { if (_variantId == WrappedOfIReadOnlyListOfStringId) - return _wrappedOfIReadOnlyListOfString!; + return _wrappedOfIReadOnlyListOfString; throw new System.InvalidOperationException("Inner value is not WrappedOfIReadOnlyListOfString"); } } @@ -116,11 +116,11 @@ public Result(global::Wrapped>(Result value) { if (value._variantId == WrappedOfIReadOnlyListOfStringId) - return value._wrappedOfIReadOnlyListOfString!; + return value._wrappedOfIReadOnlyListOfString; throw new System.InvalidOperationException("Inner value is not WrappedOfIReadOnlyListOfString"); } - public bool TryGetWrappedOfIReadOnlyListOfString([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Wrapped>? value) + public bool TryGetWrappedOfIReadOnlyListOfString([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Wrapped> value) { if (_variantId == WrappedOfIReadOnlyListOfStringId) { @@ -137,22 +137,22 @@ public bool TryGetWrappedOfIReadOnlyListOfString([System.Diagnostics.CodeAnalysi public TOut Match(global::System.Func matchSuccess, global::System.Func matchError, global::System.Func>, TOut> matchWrappedOfIReadOnlyListOfString) { if (_variantId == SuccessId) - return matchSuccess(_success!); + return matchSuccess(_success); if (_variantId == ErrorId) - return matchError(_error!); + return matchError(_error); if (_variantId == WrappedOfIReadOnlyListOfStringId) - return matchWrappedOfIReadOnlyListOfString(_wrappedOfIReadOnlyListOfString!); + return matchWrappedOfIReadOnlyListOfString(_wrappedOfIReadOnlyListOfString); throw new System.InvalidOperationException("Inner type is unknown"); } public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchSuccess, global::System.Func> matchError, global::System.Func>, global::System.Threading.CancellationToken, global::System.Threading.Tasks.Task> matchWrappedOfIReadOnlyListOfString, global::System.Threading.CancellationToken ct) { if (_variantId == SuccessId) - return await matchSuccess(_success!, ct).ConfigureAwait(false); + return await matchSuccess(_success, ct).ConfigureAwait(false); if (_variantId == ErrorId) - return await matchError(_error!, ct).ConfigureAwait(false); + return await matchError(_error, ct).ConfigureAwait(false); if (_variantId == WrappedOfIReadOnlyListOfStringId) - return await matchWrappedOfIReadOnlyListOfString(_wrappedOfIReadOnlyListOfString!, ct).ConfigureAwait(false); + return await matchWrappedOfIReadOnlyListOfString(_wrappedOfIReadOnlyListOfString, ct).ConfigureAwait(false); throw new System.InvalidOperationException("Inner type is unknown"); } @@ -160,19 +160,19 @@ public void Switch(global::System.Action switchSuccess, global: { if (_variantId == SuccessId) { - switchSuccess(_success!); + switchSuccess(_success); return; } if (_variantId == ErrorId) { - switchError(_error!); + switchError(_error); return; } if (_variantId == WrappedOfIReadOnlyListOfStringId) { - switchWrappedOfIReadOnlyListOfString(_wrappedOfIReadOnlyListOfString!); + switchWrappedOfIReadOnlyListOfString(_wrappedOfIReadOnlyListOfString); return; } @@ -183,19 +183,19 @@ public void Switch(global::System.Action switchSuccess, global: { if (_variantId == SuccessId) { - await switchSuccess(_success!, ct).ConfigureAwait(false); + await switchSuccess(_success, ct).ConfigureAwait(false); return; } if (_variantId == ErrorId) { - await switchError(_error!, ct).ConfigureAwait(false); + await switchError(_error, ct).ConfigureAwait(false); return; } if (_variantId == WrappedOfIReadOnlyListOfStringId) { - await switchWrappedOfIReadOnlyListOfString(_wrappedOfIReadOnlyListOfString!, ct).ConfigureAwait(false); + await switchWrappedOfIReadOnlyListOfString(_wrappedOfIReadOnlyListOfString, ct).ConfigureAwait(false); return; } @@ -255,11 +255,11 @@ public bool Equals(Result? other) } if (_variantId == SuccessId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_success!, other._success); + return System.Collections.Generic.EqualityComparer.Default.Equals(_success, other._success); if (_variantId == ErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_error!, other._error); + return System.Collections.Generic.EqualityComparer.Default.Equals(_error, other._error); if (_variantId == WrappedOfIReadOnlyListOfStringId) - return System.Collections.Generic.EqualityComparer>>.Default.Equals(_wrappedOfIReadOnlyListOfString!, other._wrappedOfIReadOnlyListOfString); + return System.Collections.Generic.EqualityComparer>>.Default.Equals(_wrappedOfIReadOnlyListOfString, other._wrappedOfIReadOnlyListOfString); throw new System.InvalidOperationException("Inner type is unknown"); } diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_partial-class#UnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_partial-class#UnionTypeAttribute.g.verified.cs index c9f95c1..c8f7fed 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_partial-class#UnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_partial-class#UnionTypeAttribute.g.verified.cs @@ -15,6 +15,7 @@ internal sealed class UnionTypeAttribute : Attribute public Type Type { get; } public string? Alias { get; } public int Order { get; } + public bool AllowNull { get; set; } public UnionTypeAttribute(Type type, string? alias = null, [CallerLineNumber] int order = 0) { diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_partial-struct#GenericUnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_partial-struct#GenericUnionTypeAttribute.g.verified.cs index 853ee82..e256764 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_partial-struct#GenericUnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_partial-struct#GenericUnionTypeAttribute.g.verified.cs @@ -9,8 +9,10 @@ namespace N.SourceGenerators.UnionTypes { - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] + [AttributeUsage(AttributeTargets.GenericParameter, Inherited = false, AllowMultiple = false)] internal sealed class GenericUnionTypeAttribute : Attribute { + public string? Alias { get; set; } + public bool AllowNull { get; set; } } } \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_partial-struct#Result.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_partial-struct#Result.g.verified.cs index dabe2b2..f49a856 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_partial-struct#Result.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_partial-struct#Result.g.verified.cs @@ -9,14 +9,14 @@ partial struct Result : System.IEquatable { private readonly int _variantId; private const int SuccessId = 1; - private readonly global::Success? _success; + private readonly global::Success _success; public bool IsSuccess => _variantId == SuccessId; public global::Success AsSuccess { get { if (_variantId == SuccessId) - return _success!; + return _success; throw new System.InvalidOperationException("Inner value is not Success"); } } @@ -32,11 +32,11 @@ public Result(global::Success success) public static explicit operator global::Success(Result value) { if (value._variantId == SuccessId) - return value._success!; + return value._success; throw new System.InvalidOperationException("Inner value is not Success"); } - public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Success? value) + public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Success value) { if (_variantId == SuccessId) { @@ -51,14 +51,14 @@ public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] ou } private const int ErrorId = 2; - private readonly global::Error? _error; + private readonly global::Error _error; public bool IsError => _variantId == ErrorId; public global::Error AsError { get { if (_variantId == ErrorId) - return _error!; + return _error; throw new System.InvalidOperationException("Inner value is not Error"); } } @@ -74,11 +74,11 @@ public Result(global::Error @error) public static explicit operator global::Error(Result value) { if (value._variantId == ErrorId) - return value._error!; + return value._error; throw new System.InvalidOperationException("Inner value is not Error"); } - public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Error? value) + public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Error value) { if (_variantId == ErrorId) { @@ -93,14 +93,14 @@ public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out } private const int WrappedOfIReadOnlyListOfStringId = 3; - private readonly global::Wrapped>? _wrappedOfIReadOnlyListOfString; + private readonly global::Wrapped> _wrappedOfIReadOnlyListOfString; public bool IsWrappedOfIReadOnlyListOfString => _variantId == WrappedOfIReadOnlyListOfStringId; public global::Wrapped> AsWrappedOfIReadOnlyListOfString { get { if (_variantId == WrappedOfIReadOnlyListOfStringId) - return _wrappedOfIReadOnlyListOfString!; + return _wrappedOfIReadOnlyListOfString; throw new System.InvalidOperationException("Inner value is not WrappedOfIReadOnlyListOfString"); } } @@ -116,11 +116,11 @@ public Result(global::Wrapped>(Result value) { if (value._variantId == WrappedOfIReadOnlyListOfStringId) - return value._wrappedOfIReadOnlyListOfString!; + return value._wrappedOfIReadOnlyListOfString; throw new System.InvalidOperationException("Inner value is not WrappedOfIReadOnlyListOfString"); } - public bool TryGetWrappedOfIReadOnlyListOfString([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Wrapped>? value) + public bool TryGetWrappedOfIReadOnlyListOfString([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Wrapped> value) { if (_variantId == WrappedOfIReadOnlyListOfStringId) { @@ -137,22 +137,22 @@ public bool TryGetWrappedOfIReadOnlyListOfString([System.Diagnostics.CodeAnalysi public TOut Match(global::System.Func matchSuccess, global::System.Func matchError, global::System.Func>, TOut> matchWrappedOfIReadOnlyListOfString) { if (_variantId == SuccessId) - return matchSuccess(_success!); + return matchSuccess(_success); if (_variantId == ErrorId) - return matchError(_error!); + return matchError(_error); if (_variantId == WrappedOfIReadOnlyListOfStringId) - return matchWrappedOfIReadOnlyListOfString(_wrappedOfIReadOnlyListOfString!); + return matchWrappedOfIReadOnlyListOfString(_wrappedOfIReadOnlyListOfString); throw new System.InvalidOperationException("Inner type is unknown"); } public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchSuccess, global::System.Func> matchError, global::System.Func>, global::System.Threading.CancellationToken, global::System.Threading.Tasks.Task> matchWrappedOfIReadOnlyListOfString, global::System.Threading.CancellationToken ct) { if (_variantId == SuccessId) - return await matchSuccess(_success!, ct).ConfigureAwait(false); + return await matchSuccess(_success, ct).ConfigureAwait(false); if (_variantId == ErrorId) - return await matchError(_error!, ct).ConfigureAwait(false); + return await matchError(_error, ct).ConfigureAwait(false); if (_variantId == WrappedOfIReadOnlyListOfStringId) - return await matchWrappedOfIReadOnlyListOfString(_wrappedOfIReadOnlyListOfString!, ct).ConfigureAwait(false); + return await matchWrappedOfIReadOnlyListOfString(_wrappedOfIReadOnlyListOfString, ct).ConfigureAwait(false); throw new System.InvalidOperationException("Inner type is unknown"); } @@ -160,19 +160,19 @@ public void Switch(global::System.Action switchSuccess, global: { if (_variantId == SuccessId) { - switchSuccess(_success!); + switchSuccess(_success); return; } if (_variantId == ErrorId) { - switchError(_error!); + switchError(_error); return; } if (_variantId == WrappedOfIReadOnlyListOfStringId) { - switchWrappedOfIReadOnlyListOfString(_wrappedOfIReadOnlyListOfString!); + switchWrappedOfIReadOnlyListOfString(_wrappedOfIReadOnlyListOfString); return; } @@ -183,19 +183,19 @@ public void Switch(global::System.Action switchSuccess, global: { if (_variantId == SuccessId) { - await switchSuccess(_success!, ct).ConfigureAwait(false); + await switchSuccess(_success, ct).ConfigureAwait(false); return; } if (_variantId == ErrorId) { - await switchError(_error!, ct).ConfigureAwait(false); + await switchError(_error, ct).ConfigureAwait(false); return; } if (_variantId == WrappedOfIReadOnlyListOfStringId) { - await switchWrappedOfIReadOnlyListOfString(_wrappedOfIReadOnlyListOfString!, ct).ConfigureAwait(false); + await switchWrappedOfIReadOnlyListOfString(_wrappedOfIReadOnlyListOfString, ct).ConfigureAwait(false); return; } @@ -245,11 +245,11 @@ public bool Equals(Result other) } if (_variantId == SuccessId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_success!, other._success); + return System.Collections.Generic.EqualityComparer.Default.Equals(_success, other._success); if (_variantId == ErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_error!, other._error); + return System.Collections.Generic.EqualityComparer.Default.Equals(_error, other._error); if (_variantId == WrappedOfIReadOnlyListOfStringId) - return System.Collections.Generic.EqualityComparer>>.Default.Equals(_wrappedOfIReadOnlyListOfString!, other._wrappedOfIReadOnlyListOfString); + return System.Collections.Generic.EqualityComparer>>.Default.Equals(_wrappedOfIReadOnlyListOfString, other._wrappedOfIReadOnlyListOfString); throw new System.InvalidOperationException("Inner type is unknown"); } diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_partial-struct#UnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_partial-struct#UnionTypeAttribute.g.verified.cs index c9f95c1..c8f7fed 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_partial-struct#UnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_partial-struct#UnionTypeAttribute.g.verified.cs @@ -15,6 +15,7 @@ internal sealed class UnionTypeAttribute : Attribute public Type Type { get; } public string? Alias { get; } public int Order { get; } + public bool AllowNull { get; set; } public UnionTypeAttribute(Type type, string? alias = null, [CallerLineNumber] int order = 0) { diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_readonly-partial-struct#GenericUnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_readonly-partial-struct#GenericUnionTypeAttribute.g.verified.cs index 853ee82..e256764 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_readonly-partial-struct#GenericUnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_readonly-partial-struct#GenericUnionTypeAttribute.g.verified.cs @@ -9,8 +9,10 @@ namespace N.SourceGenerators.UnionTypes { - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] + [AttributeUsage(AttributeTargets.GenericParameter, Inherited = false, AllowMultiple = false)] internal sealed class GenericUnionTypeAttribute : Attribute { + public string? Alias { get; set; } + public bool AllowNull { get; set; } } } \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_readonly-partial-struct#Result.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_readonly-partial-struct#Result.g.verified.cs index dabe2b2..f49a856 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_readonly-partial-struct#Result.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_readonly-partial-struct#Result.g.verified.cs @@ -9,14 +9,14 @@ partial struct Result : System.IEquatable { private readonly int _variantId; private const int SuccessId = 1; - private readonly global::Success? _success; + private readonly global::Success _success; public bool IsSuccess => _variantId == SuccessId; public global::Success AsSuccess { get { if (_variantId == SuccessId) - return _success!; + return _success; throw new System.InvalidOperationException("Inner value is not Success"); } } @@ -32,11 +32,11 @@ public Result(global::Success success) public static explicit operator global::Success(Result value) { if (value._variantId == SuccessId) - return value._success!; + return value._success; throw new System.InvalidOperationException("Inner value is not Success"); } - public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Success? value) + public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Success value) { if (_variantId == SuccessId) { @@ -51,14 +51,14 @@ public bool TryGetSuccess([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] ou } private const int ErrorId = 2; - private readonly global::Error? _error; + private readonly global::Error _error; public bool IsError => _variantId == ErrorId; public global::Error AsError { get { if (_variantId == ErrorId) - return _error!; + return _error; throw new System.InvalidOperationException("Inner value is not Error"); } } @@ -74,11 +74,11 @@ public Result(global::Error @error) public static explicit operator global::Error(Result value) { if (value._variantId == ErrorId) - return value._error!; + return value._error; throw new System.InvalidOperationException("Inner value is not Error"); } - public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Error? value) + public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Error value) { if (_variantId == ErrorId) { @@ -93,14 +93,14 @@ public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out } private const int WrappedOfIReadOnlyListOfStringId = 3; - private readonly global::Wrapped>? _wrappedOfIReadOnlyListOfString; + private readonly global::Wrapped> _wrappedOfIReadOnlyListOfString; public bool IsWrappedOfIReadOnlyListOfString => _variantId == WrappedOfIReadOnlyListOfStringId; public global::Wrapped> AsWrappedOfIReadOnlyListOfString { get { if (_variantId == WrappedOfIReadOnlyListOfStringId) - return _wrappedOfIReadOnlyListOfString!; + return _wrappedOfIReadOnlyListOfString; throw new System.InvalidOperationException("Inner value is not WrappedOfIReadOnlyListOfString"); } } @@ -116,11 +116,11 @@ public Result(global::Wrapped>(Result value) { if (value._variantId == WrappedOfIReadOnlyListOfStringId) - return value._wrappedOfIReadOnlyListOfString!; + return value._wrappedOfIReadOnlyListOfString; throw new System.InvalidOperationException("Inner value is not WrappedOfIReadOnlyListOfString"); } - public bool TryGetWrappedOfIReadOnlyListOfString([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Wrapped>? value) + public bool TryGetWrappedOfIReadOnlyListOfString([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::Wrapped> value) { if (_variantId == WrappedOfIReadOnlyListOfStringId) { @@ -137,22 +137,22 @@ public bool TryGetWrappedOfIReadOnlyListOfString([System.Diagnostics.CodeAnalysi public TOut Match(global::System.Func matchSuccess, global::System.Func matchError, global::System.Func>, TOut> matchWrappedOfIReadOnlyListOfString) { if (_variantId == SuccessId) - return matchSuccess(_success!); + return matchSuccess(_success); if (_variantId == ErrorId) - return matchError(_error!); + return matchError(_error); if (_variantId == WrappedOfIReadOnlyListOfStringId) - return matchWrappedOfIReadOnlyListOfString(_wrappedOfIReadOnlyListOfString!); + return matchWrappedOfIReadOnlyListOfString(_wrappedOfIReadOnlyListOfString); throw new System.InvalidOperationException("Inner type is unknown"); } public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchSuccess, global::System.Func> matchError, global::System.Func>, global::System.Threading.CancellationToken, global::System.Threading.Tasks.Task> matchWrappedOfIReadOnlyListOfString, global::System.Threading.CancellationToken ct) { if (_variantId == SuccessId) - return await matchSuccess(_success!, ct).ConfigureAwait(false); + return await matchSuccess(_success, ct).ConfigureAwait(false); if (_variantId == ErrorId) - return await matchError(_error!, ct).ConfigureAwait(false); + return await matchError(_error, ct).ConfigureAwait(false); if (_variantId == WrappedOfIReadOnlyListOfStringId) - return await matchWrappedOfIReadOnlyListOfString(_wrappedOfIReadOnlyListOfString!, ct).ConfigureAwait(false); + return await matchWrappedOfIReadOnlyListOfString(_wrappedOfIReadOnlyListOfString, ct).ConfigureAwait(false); throw new System.InvalidOperationException("Inner type is unknown"); } @@ -160,19 +160,19 @@ public void Switch(global::System.Action switchSuccess, global: { if (_variantId == SuccessId) { - switchSuccess(_success!); + switchSuccess(_success); return; } if (_variantId == ErrorId) { - switchError(_error!); + switchError(_error); return; } if (_variantId == WrappedOfIReadOnlyListOfStringId) { - switchWrappedOfIReadOnlyListOfString(_wrappedOfIReadOnlyListOfString!); + switchWrappedOfIReadOnlyListOfString(_wrappedOfIReadOnlyListOfString); return; } @@ -183,19 +183,19 @@ public void Switch(global::System.Action switchSuccess, global: { if (_variantId == SuccessId) { - await switchSuccess(_success!, ct).ConfigureAwait(false); + await switchSuccess(_success, ct).ConfigureAwait(false); return; } if (_variantId == ErrorId) { - await switchError(_error!, ct).ConfigureAwait(false); + await switchError(_error, ct).ConfigureAwait(false); return; } if (_variantId == WrappedOfIReadOnlyListOfStringId) { - await switchWrappedOfIReadOnlyListOfString(_wrappedOfIReadOnlyListOfString!, ct).ConfigureAwait(false); + await switchWrappedOfIReadOnlyListOfString(_wrappedOfIReadOnlyListOfString, ct).ConfigureAwait(false); return; } @@ -245,11 +245,11 @@ public bool Equals(Result other) } if (_variantId == SuccessId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_success!, other._success); + return System.Collections.Generic.EqualityComparer.Default.Equals(_success, other._success); if (_variantId == ErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_error!, other._error); + return System.Collections.Generic.EqualityComparer.Default.Equals(_error, other._error); if (_variantId == WrappedOfIReadOnlyListOfStringId) - return System.Collections.Generic.EqualityComparer>>.Default.Equals(_wrappedOfIReadOnlyListOfString!, other._wrappedOfIReadOnlyListOfString); + return System.Collections.Generic.EqualityComparer>>.Default.Equals(_wrappedOfIReadOnlyListOfString, other._wrappedOfIReadOnlyListOfString); throw new System.InvalidOperationException("Inner type is unknown"); } diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_readonly-partial-struct#UnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_readonly-partial-struct#UnionTypeAttribute.g.verified.cs index c9f95c1..c8f7fed 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_readonly-partial-struct#UnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GeneratorTests.WithoutNamespace_readonly-partial-struct#UnionTypeAttribute.g.verified.cs @@ -15,6 +15,7 @@ internal sealed class UnionTypeAttribute : Attribute public Type Type { get; } public string? Alias { get; } public int Order { get; } + public bool AllowNull { get; set; } public UnionTypeAttribute(Type type, string? alias = null, [CallerLineNumber] int order = 0) { diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.OnlyGenericTypes#GenericUnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.OnlyGenericTypes#GenericUnionTypeAttribute.g.verified.cs index 853ee82..e256764 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.OnlyGenericTypes#GenericUnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.OnlyGenericTypes#GenericUnionTypeAttribute.g.verified.cs @@ -9,8 +9,10 @@ namespace N.SourceGenerators.UnionTypes { - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] + [AttributeUsage(AttributeTargets.GenericParameter, Inherited = false, AllowMultiple = false)] internal sealed class GenericUnionTypeAttribute : Attribute { + public string? Alias { get; set; } + public bool AllowNull { get; set; } } } \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.OnlyGenericTypes#OperationDataResultOfTAndTError.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.OnlyGenericTypes#OperationDataResultOfTAndTError.g.verified.cs new file mode 100644 index 0000000..4ac50ea --- /dev/null +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.OnlyGenericTypes#OperationDataResultOfTAndTError.g.verified.cs @@ -0,0 +1,230 @@ +//HintName: OperationDataResultOfTAndTError.g.cs +// +// This code was generated by https://github.com/Ne4to/N.SourceGenerators.UnionTypes +// Feel free to open an issue +// +#pragma warning disable +#nullable enable +partial class OperationDataResult : System.IEquatable> +{ + private readonly int _variantId; + private const int ResultId = 1; + private readonly T _result; + public bool IsResult => _variantId == ResultId; + public T AsResult + { + get + { + if (_variantId == ResultId) + return _result; + throw new System.InvalidOperationException("Inner value is not Result"); + } + } + + public OperationDataResult(T result) + { + System.ArgumentNullException.ThrowIfNull(result); + _variantId = ResultId; + _result = result; + } + + public static implicit operator OperationDataResult(T result) => new OperationDataResult(result); + public static explicit operator T(OperationDataResult value) + { + if (value._variantId == ResultId) + return value._result; + throw new System.InvalidOperationException("Inner value is not Result"); + } + + public bool TryGetResult([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out T value) + { + if (_variantId == ResultId) + { + value = _result; + return true; + } + else + { + value = default; + return false; + } + } + + private const int ErrorId = 2; + private readonly TError _error; + public bool IsError => _variantId == ErrorId; + public TError AsError + { + get + { + if (_variantId == ErrorId) + return _error; + throw new System.InvalidOperationException("Inner value is not Error"); + } + } + + public OperationDataResult(TError @error) + { + System.ArgumentNullException.ThrowIfNull(@error); + _variantId = ErrorId; + _error = @error; + } + + public static implicit operator OperationDataResult(TError @error) => new OperationDataResult(@error); + public static explicit operator TError(OperationDataResult value) + { + if (value._variantId == ErrorId) + return value._error; + throw new System.InvalidOperationException("Inner value is not Error"); + } + + public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out TError value) + { + if (_variantId == ErrorId) + { + value = _error; + return true; + } + else + { + value = default; + return false; + } + } + + public TOut Match(global::System.Func matchResult, global::System.Func matchError) + { + if (_variantId == ResultId) + return matchResult(_result); + if (_variantId == ErrorId) + return matchError(_error); + throw new System.InvalidOperationException("Inner type is unknown"); + } + + public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchResult, global::System.Func> matchError, global::System.Threading.CancellationToken ct) + { + if (_variantId == ResultId) + return await matchResult(_result, ct).ConfigureAwait(false); + if (_variantId == ErrorId) + return await matchError(_error, ct).ConfigureAwait(false); + throw new System.InvalidOperationException("Inner type is unknown"); + } + + public void Switch(global::System.Action switchResult, global::System.Action switchError) + { + if (_variantId == ResultId) + { + switchResult(_result); + return; + } + + if (_variantId == ErrorId) + { + switchError(_error); + return; + } + + throw new System.InvalidOperationException("Inner type is unknown"); + } + + public async global::System.Threading.Tasks.Task SwitchAsync(global::System.Func switchResult, global::System.Func switchError, global::System.Threading.CancellationToken ct) + { + if (_variantId == ResultId) + { + await switchResult(_result, ct).ConfigureAwait(false); + return; + } + + if (_variantId == ErrorId) + { + await switchError(_error, ct).ConfigureAwait(false); + return; + } + + throw new System.InvalidOperationException("Inner type is unknown"); + } + + public global::System.Type ValueType + { + get + { + if (_variantId == ResultId) + return typeof(T); + if (_variantId == ErrorId) + return typeof(TError); + throw new System.InvalidOperationException("Inner type is unknown"); + } + } + + public override int GetHashCode() + { + if (_variantId == ResultId) + return _result.GetHashCode(); + if (_variantId == ErrorId) + return _error.GetHashCode(); + throw new System.InvalidOperationException("Inner type is unknown"); + } + + public static bool operator ==(OperationDataResult? left, OperationDataResult? right) + { + return Equals(left, right); + } + + public static bool operator !=(OperationDataResult? left, OperationDataResult? right) + { + return !Equals(left, right); + } + + public bool Equals(OperationDataResult? other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + if (ValueType != other.ValueType) + { + return false; + } + + if (_variantId == ResultId) + return System.Collections.Generic.EqualityComparer.Default.Equals(_result, other._result); + if (_variantId == ErrorId) + return System.Collections.Generic.EqualityComparer.Default.Equals(_error, other._error); + throw new System.InvalidOperationException("Inner type is unknown"); + } + + public override string ToString() + { + if (_variantId == ResultId) + return _result.ToString(); + if (_variantId == ErrorId) + return _error.ToString(); + throw new System.InvalidOperationException("Inner type is unknown"); + } + + public override bool Equals(object? other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + if (other.GetType() != typeof(OperationDataResult)) + { + return false; + } + + return Equals((OperationDataResult)other); + } +} \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.OnlyGenericTypes#OperationDataResultOfTResultAndTError.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.OnlyGenericTypes#OperationDataResultOfTResultAndTError.g.verified.cs index 52f1f85..ef06d0e 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.OnlyGenericTypes#OperationDataResultOfTResultAndTError.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.OnlyGenericTypes#OperationDataResultOfTResultAndTError.g.verified.cs @@ -9,14 +9,14 @@ partial class OperationDataResult : System.IEquatable _variantId == ResultId; public TResult AsResult { get { if (_variantId == ResultId) - return _result!; + return _result; throw new System.InvalidOperationException("Inner value is not Result"); } } @@ -32,11 +32,11 @@ public OperationDataResult(TResult result) public static explicit operator TResult(OperationDataResult value) { if (value._variantId == ResultId) - return value._result!; + return value._result; throw new System.InvalidOperationException("Inner value is not Result"); } - public bool TryGetResult([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out TResult? value) + public bool TryGetResult([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out TResult value) { if (_variantId == ResultId) { @@ -51,14 +51,14 @@ public bool TryGetResult([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out } private const int ErrorId = 2; - private readonly TError? _error; + private readonly TError _error; public bool IsError => _variantId == ErrorId; public TError AsError { get { if (_variantId == ErrorId) - return _error!; + return _error; throw new System.InvalidOperationException("Inner value is not Error"); } } @@ -74,11 +74,11 @@ public OperationDataResult(TError @error) public static explicit operator TError(OperationDataResult value) { if (value._variantId == ErrorId) - return value._error!; + return value._error; throw new System.InvalidOperationException("Inner value is not Error"); } - public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out TError? value) + public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out TError value) { if (_variantId == ErrorId) { @@ -95,18 +95,18 @@ public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out public TOut Match(global::System.Func matchResult, global::System.Func matchError) { if (_variantId == ResultId) - return matchResult(_result!); + return matchResult(_result); if (_variantId == ErrorId) - return matchError(_error!); + return matchError(_error); throw new System.InvalidOperationException("Inner type is unknown"); } public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchResult, global::System.Func> matchError, global::System.Threading.CancellationToken ct) { if (_variantId == ResultId) - return await matchResult(_result!, ct).ConfigureAwait(false); + return await matchResult(_result, ct).ConfigureAwait(false); if (_variantId == ErrorId) - return await matchError(_error!, ct).ConfigureAwait(false); + return await matchError(_error, ct).ConfigureAwait(false); throw new System.InvalidOperationException("Inner type is unknown"); } @@ -114,13 +114,13 @@ public void Switch(global::System.Action switchResult, global::System.A { if (_variantId == ResultId) { - switchResult(_result!); + switchResult(_result); return; } if (_variantId == ErrorId) { - switchError(_error!); + switchError(_error); return; } @@ -131,13 +131,13 @@ public void Switch(global::System.Action switchResult, global::System.A { if (_variantId == ResultId) { - await switchResult(_result!, ct).ConfigureAwait(false); + await switchResult(_result, ct).ConfigureAwait(false); return; } if (_variantId == ErrorId) { - await switchError(_error!, ct).ConfigureAwait(false); + await switchError(_error, ct).ConfigureAwait(false); return; } @@ -193,9 +193,9 @@ public bool Equals(OperationDataResult? other) } if (_variantId == ResultId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_result!, other._result); + return System.Collections.Generic.EqualityComparer.Default.Equals(_result, other._result); if (_variantId == ErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_error!, other._error); + return System.Collections.Generic.EqualityComparer.Default.Equals(_error, other._error); throw new System.InvalidOperationException("Inner type is unknown"); } diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.OnlyGenericTypes#UnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.OnlyGenericTypes#UnionTypeAttribute.g.verified.cs index c9f95c1..c8f7fed 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.OnlyGenericTypes#UnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.OnlyGenericTypes#UnionTypeAttribute.g.verified.cs @@ -15,6 +15,7 @@ internal sealed class UnionTypeAttribute : Attribute public Type Type { get; } public string? Alias { get; } public int Order { get; } + public bool AllowNull { get; set; } public UnionTypeAttribute(Type type, string? alias = null, [CallerLineNumber] int order = 0) { diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.WithAlias#GenericResultNullableOfT.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.WithAlias#GenericResultNullableOfT.g.verified.cs new file mode 100644 index 0000000..15f93cf --- /dev/null +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.WithAlias#GenericResultNullableOfT.g.verified.cs @@ -0,0 +1,228 @@ +//HintName: GenericResultNullableOfT.g.cs +// +// This code was generated by https://github.com/Ne4to/N.SourceGenerators.UnionTypes +// Feel free to open an issue +// +#pragma warning disable +#nullable enable +partial class GenericResultNullable : System.IEquatable> +{ + private readonly int _variantId; + private const int ValueId = 1; + private readonly T _value; + public bool IsValue => _variantId == ValueId; + public T AsValue + { + get + { + if (_variantId == ValueId) + return _value; + throw new System.InvalidOperationException("Inner value is not Value"); + } + } + + public GenericResultNullable(T value) + { + _variantId = ValueId; + _value = value; + } + + public static implicit operator GenericResultNullable(T value) => new GenericResultNullable(value); + public static explicit operator T(GenericResultNullable value) + { + if (value._variantId == ValueId) + return value._value; + throw new System.InvalidOperationException("Inner value is not Value"); + } + + public bool TryGetValue(out T value) + { + if (_variantId == ValueId) + { + value = _value; + return true; + } + else + { + value = default; + return false; + } + } + + private const int StatusId = 2; + private readonly string _status; + public bool IsStatus => _variantId == StatusId; + public string AsStatus + { + get + { + if (_variantId == StatusId) + return _status; + throw new System.InvalidOperationException("Inner value is not Status"); + } + } + + public GenericResultNullable(string status) + { + _variantId = StatusId; + _status = status; + } + + public static implicit operator GenericResultNullable(string status) => new GenericResultNullable(status); + public static explicit operator string(GenericResultNullable value) + { + if (value._variantId == StatusId) + return value._status; + throw new System.InvalidOperationException("Inner value is not Status"); + } + + public bool TryGetStatus(out string value) + { + if (_variantId == StatusId) + { + value = _status; + return true; + } + else + { + value = default; + return false; + } + } + + public TOut Match(global::System.Func matchValue, global::System.Func matchStatus) + { + if (_variantId == ValueId) + return matchValue(_value); + if (_variantId == StatusId) + return matchStatus(_status); + throw new System.InvalidOperationException("Inner type is unknown"); + } + + public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchValue, global::System.Func> matchStatus, global::System.Threading.CancellationToken ct) + { + if (_variantId == ValueId) + return await matchValue(_value, ct).ConfigureAwait(false); + if (_variantId == StatusId) + return await matchStatus(_status, ct).ConfigureAwait(false); + throw new System.InvalidOperationException("Inner type is unknown"); + } + + public void Switch(global::System.Action switchValue, global::System.Action switchStatus) + { + if (_variantId == ValueId) + { + switchValue(_value); + return; + } + + if (_variantId == StatusId) + { + switchStatus(_status); + return; + } + + throw new System.InvalidOperationException("Inner type is unknown"); + } + + public async global::System.Threading.Tasks.Task SwitchAsync(global::System.Func switchValue, global::System.Func switchStatus, global::System.Threading.CancellationToken ct) + { + if (_variantId == ValueId) + { + await switchValue(_value, ct).ConfigureAwait(false); + return; + } + + if (_variantId == StatusId) + { + await switchStatus(_status, ct).ConfigureAwait(false); + return; + } + + throw new System.InvalidOperationException("Inner type is unknown"); + } + + public global::System.Type ValueType + { + get + { + if (_variantId == ValueId) + return typeof(T); + if (_variantId == StatusId) + return typeof(string); + throw new System.InvalidOperationException("Inner type is unknown"); + } + } + + public override int GetHashCode() + { + if (_variantId == ValueId) + return _value.GetHashCode(); + if (_variantId == StatusId) + return _status.GetHashCode(); + throw new System.InvalidOperationException("Inner type is unknown"); + } + + public static bool operator ==(GenericResultNullable? left, GenericResultNullable? right) + { + return Equals(left, right); + } + + public static bool operator !=(GenericResultNullable? left, GenericResultNullable? right) + { + return !Equals(left, right); + } + + public bool Equals(GenericResultNullable? other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + if (ValueType != other.ValueType) + { + return false; + } + + if (_variantId == ValueId) + return System.Collections.Generic.EqualityComparer.Default.Equals(_value, other._value); + if (_variantId == StatusId) + return System.Collections.Generic.EqualityComparer.Default.Equals(_status, other._status); + throw new System.InvalidOperationException("Inner type is unknown"); + } + + public override string ToString() + { + if (_variantId == ValueId) + return _value.ToString(); + if (_variantId == StatusId) + return _status.ToString(); + throw new System.InvalidOperationException("Inner type is unknown"); + } + + public override bool Equals(object? other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + if (other.GetType() != typeof(GenericResultNullable)) + { + return false; + } + + return Equals((GenericResultNullable)other); + } +} \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.WithAlias#GenericUnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.WithAlias#GenericUnionTypeAttribute.g.verified.cs new file mode 100644 index 0000000..e256764 --- /dev/null +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.WithAlias#GenericUnionTypeAttribute.g.verified.cs @@ -0,0 +1,18 @@ +//HintName: GenericUnionTypeAttribute.g.cs +// +// This code was generated by https://github.com/Ne4to/N.SourceGenerators.UnionTypes +// Feel free to open an issue +// +#nullable enable +using System; +using System.Runtime.CompilerServices; + +namespace N.SourceGenerators.UnionTypes +{ + [AttributeUsage(AttributeTargets.GenericParameter, Inherited = false, AllowMultiple = false)] + internal sealed class GenericUnionTypeAttribute : Attribute + { + public string? Alias { get; set; } + public bool AllowNull { get; set; } + } +} \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.WithAlias#UnionConverterAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.WithAlias#UnionConverterAttribute.g.verified.cs new file mode 100644 index 0000000..3e6fd2b --- /dev/null +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.WithAlias#UnionConverterAttribute.g.verified.cs @@ -0,0 +1,22 @@ +//HintName: UnionConverterAttribute.g.cs +#nullable enable +using System; +using System.Runtime.CompilerServices; + +namespace N.SourceGenerators.UnionTypes +{ + [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)] + sealed class UnionConverterAttribute : Attribute + { + public Type FromType { get; } + public Type ToType { get; } + public string? MethodName { get; } + + public UnionConverterAttribute(Type fromType, Type toType, string? methodName = null) + { + FromType = fromType; + ToType = toType; + MethodName = methodName; + } + } +} \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.WithAlias#UnionConverterFromAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.WithAlias#UnionConverterFromAttribute.g.verified.cs new file mode 100644 index 0000000..d740ef3 --- /dev/null +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.WithAlias#UnionConverterFromAttribute.g.verified.cs @@ -0,0 +1,22 @@ +//HintName: UnionConverterFromAttribute.g.cs +// +// This code was generated by https://github.com/Ne4to/N.SourceGenerators.UnionTypes +// Feel free to open an issue +// +#nullable enable +using System; +using System.Runtime.CompilerServices; + +namespace N.SourceGenerators.UnionTypes +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = true)] + sealed class UnionConverterFromAttribute : Attribute + { + public Type FromType { get; } + + public UnionConverterFromAttribute(Type fromType) + { + FromType = fromType; + } + } +} \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.WithAlias#UnionConverterToAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.WithAlias#UnionConverterToAttribute.g.verified.cs new file mode 100644 index 0000000..fae1e4d --- /dev/null +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.WithAlias#UnionConverterToAttribute.g.verified.cs @@ -0,0 +1,22 @@ +//HintName: UnionConverterToAttribute.g.cs +// +// This code was generated by https://github.com/Ne4to/N.SourceGenerators.UnionTypes +// Feel free to open an issue +// +#nullable enable +using System; +using System.Runtime.CompilerServices; + +namespace N.SourceGenerators.UnionTypes +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = true)] + sealed class UnionConverterToAttribute : Attribute + { + public Type ToType { get; } + + public UnionConverterToAttribute(Type toType) + { + ToType = toType; + } + } +} \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.WithAlias#UnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.WithAlias#UnionTypeAttribute.g.verified.cs new file mode 100644 index 0000000..c8f7fed --- /dev/null +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.WithAlias#UnionTypeAttribute.g.verified.cs @@ -0,0 +1,27 @@ +//HintName: UnionTypeAttribute.g.cs +// +// This code was generated by https://github.com/Ne4to/N.SourceGenerators.UnionTypes +// Feel free to open an issue +// +#nullable enable +using System; +using System.Runtime.CompilerServices; + +namespace N.SourceGenerators.UnionTypes +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = true)] + internal sealed class UnionTypeAttribute : Attribute + { + public Type Type { get; } + public string? Alias { get; } + public int Order { get; } + public bool AllowNull { get; set; } + + public UnionTypeAttribute(Type type, string? alias = null, [CallerLineNumber] int order = 0) + { + Type = type; + Alias = alias; + Order = order; + } + } +} \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.WithCustomUnionType#GenericUnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.WithCustomUnionType#GenericUnionTypeAttribute.g.verified.cs index 853ee82..e256764 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.WithCustomUnionType#GenericUnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.WithCustomUnionType#GenericUnionTypeAttribute.g.verified.cs @@ -9,8 +9,10 @@ namespace N.SourceGenerators.UnionTypes { - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] + [AttributeUsage(AttributeTargets.GenericParameter, Inherited = false, AllowMultiple = false)] internal sealed class GenericUnionTypeAttribute : Attribute { + public string? Alias { get; set; } + public bool AllowNull { get; set; } } } \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.WithCustomUnionType#OperationDataResultOfTResultAndTError.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.WithCustomUnionType#OperationDataResultOfTResultAndTError.g.verified.cs index 679c743..246a253 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.WithCustomUnionType#OperationDataResultOfTResultAndTError.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.WithCustomUnionType#OperationDataResultOfTResultAndTError.g.verified.cs @@ -9,14 +9,14 @@ partial class OperationDataResult : System.IEquatable _variantId == ResultId; public TResult AsResult { get { if (_variantId == ResultId) - return _result!; + return _result; throw new System.InvalidOperationException("Inner value is not Result"); } } @@ -32,11 +32,11 @@ public OperationDataResult(TResult result) public static explicit operator TResult(OperationDataResult value) { if (value._variantId == ResultId) - return value._result!; + return value._result; throw new System.InvalidOperationException("Inner value is not Result"); } - public bool TryGetResult([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out TResult? value) + public bool TryGetResult([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out TResult value) { if (_variantId == ResultId) { @@ -51,14 +51,14 @@ public bool TryGetResult([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out } private const int ErrorId = 2; - private readonly TError? _error; + private readonly TError _error; public bool IsError => _variantId == ErrorId; public TError AsError { get { if (_variantId == ErrorId) - return _error!; + return _error; throw new System.InvalidOperationException("Inner value is not Error"); } } @@ -74,11 +74,11 @@ public OperationDataResult(TError @error) public static explicit operator TError(OperationDataResult value) { if (value._variantId == ErrorId) - return value._error!; + return value._error; throw new System.InvalidOperationException("Inner value is not Error"); } - public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out TError? value) + public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out TError value) { if (_variantId == ErrorId) { @@ -93,14 +93,14 @@ public bool TryGetError([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out } private const int Int32Id = 3; - private readonly int? _int32; + private readonly int _int32; public bool IsInt32 => _variantId == Int32Id; public int AsInt32 { get { if (_variantId == Int32Id) - return _int32.Value; + return _int32; throw new System.InvalidOperationException("Inner value is not Int32"); } } @@ -116,11 +116,11 @@ public OperationDataResult(int int32) public static explicit operator int(OperationDataResult value) { if (value._variantId == Int32Id) - return value._int32.Value; + return value._int32; throw new System.InvalidOperationException("Inner value is not Int32"); } - public bool TryGetInt32([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out int? value) + public bool TryGetInt32([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out int value) { if (_variantId == Int32Id) { @@ -137,22 +137,22 @@ public bool TryGetInt32([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out public TOut Match(global::System.Func matchResult, global::System.Func matchError, global::System.Func matchInt32) { if (_variantId == ResultId) - return matchResult(_result!); + return matchResult(_result); if (_variantId == ErrorId) - return matchError(_error!); + return matchError(_error); if (_variantId == Int32Id) - return matchInt32(_int32.Value); + return matchInt32(_int32); throw new System.InvalidOperationException("Inner type is unknown"); } public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchResult, global::System.Func> matchError, global::System.Func> matchInt32, global::System.Threading.CancellationToken ct) { if (_variantId == ResultId) - return await matchResult(_result!, ct).ConfigureAwait(false); + return await matchResult(_result, ct).ConfigureAwait(false); if (_variantId == ErrorId) - return await matchError(_error!, ct).ConfigureAwait(false); + return await matchError(_error, ct).ConfigureAwait(false); if (_variantId == Int32Id) - return await matchInt32(_int32.Value, ct).ConfigureAwait(false); + return await matchInt32(_int32, ct).ConfigureAwait(false); throw new System.InvalidOperationException("Inner type is unknown"); } @@ -160,19 +160,19 @@ public void Switch(global::System.Action switchResult, global::System.A { if (_variantId == ResultId) { - switchResult(_result!); + switchResult(_result); return; } if (_variantId == ErrorId) { - switchError(_error!); + switchError(_error); return; } if (_variantId == Int32Id) { - switchInt32(_int32.Value); + switchInt32(_int32); return; } @@ -183,19 +183,19 @@ public void Switch(global::System.Action switchResult, global::System.A { if (_variantId == ResultId) { - await switchResult(_result!, ct).ConfigureAwait(false); + await switchResult(_result, ct).ConfigureAwait(false); return; } if (_variantId == ErrorId) { - await switchError(_error!, ct).ConfigureAwait(false); + await switchError(_error, ct).ConfigureAwait(false); return; } if (_variantId == Int32Id) { - await switchInt32(_int32.Value, ct).ConfigureAwait(false); + await switchInt32(_int32, ct).ConfigureAwait(false); return; } @@ -255,11 +255,11 @@ public bool Equals(OperationDataResult? other) } if (_variantId == ResultId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_result!, other._result); + return System.Collections.Generic.EqualityComparer.Default.Equals(_result, other._result); if (_variantId == ErrorId) - return System.Collections.Generic.EqualityComparer.Default.Equals(_error!, other._error); + return System.Collections.Generic.EqualityComparer.Default.Equals(_error, other._error); if (_variantId == Int32Id) - return System.Collections.Generic.EqualityComparer.Default.Equals(_int32.Value, other._int32.Value); + return System.Collections.Generic.EqualityComparer.Default.Equals(_int32, other._int32); throw new System.InvalidOperationException("Inner type is unknown"); } diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.WithCustomUnionType#UnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.WithCustomUnionType#UnionTypeAttribute.g.verified.cs index c9f95c1..c8f7fed 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.WithCustomUnionType#UnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/GenericUnionTests.WithCustomUnionType#UnionTypeAttribute.g.verified.cs @@ -15,6 +15,7 @@ internal sealed class UnionTypeAttribute : Attribute public Type Type { get; } public string? Alias { get; } public int Order { get; } + public bool AllowNull { get; set; } public UnionTypeAttribute(Type type, string? alias = null, [CallerLineNumber] int order = 0) { diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/NullableValueTests.UseAllowNullAttribute#GenericUnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/NullableValueTests.UseAllowNullAttribute#GenericUnionTypeAttribute.g.verified.cs new file mode 100644 index 0000000..e256764 --- /dev/null +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/NullableValueTests.UseAllowNullAttribute#GenericUnionTypeAttribute.g.verified.cs @@ -0,0 +1,18 @@ +//HintName: GenericUnionTypeAttribute.g.cs +// +// This code was generated by https://github.com/Ne4to/N.SourceGenerators.UnionTypes +// Feel free to open an issue +// +#nullable enable +using System; +using System.Runtime.CompilerServices; + +namespace N.SourceGenerators.UnionTypes +{ + [AttributeUsage(AttributeTargets.GenericParameter, Inherited = false, AllowMultiple = false)] + internal sealed class GenericUnionTypeAttribute : Attribute + { + public string? Alias { get; set; } + public bool AllowNull { get; set; } + } +} \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/NullableValueTests.UseAllowNullAttribute#Result.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/NullableValueTests.UseAllowNullAttribute#Result.g.verified.cs new file mode 100644 index 0000000..779c4d0 --- /dev/null +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/NullableValueTests.UseAllowNullAttribute#Result.g.verified.cs @@ -0,0 +1,229 @@ +//HintName: Result.g.cs +// +// This code was generated by https://github.com/Ne4to/N.SourceGenerators.UnionTypes +// Feel free to open an issue +// +#pragma warning disable +#nullable enable +partial class Result : System.IEquatable +{ + private readonly int _variantId; + private const int NullableOfInt32Id = 1; + private readonly int? _nullableOfInt32; + public bool IsNullableOfInt32 => _variantId == NullableOfInt32Id; + public int? AsNullableOfInt32 + { + get + { + if (_variantId == NullableOfInt32Id) + return _nullableOfInt32; + throw new System.InvalidOperationException("Inner value is not NullableOfInt32"); + } + } + + public Result(int? nullableOfInt32) + { + _variantId = NullableOfInt32Id; + _nullableOfInt32 = nullableOfInt32; + } + + public static implicit operator Result(int? nullableOfInt32) => new Result(nullableOfInt32); + public static explicit operator int?(Result value) + { + if (value._variantId == NullableOfInt32Id) + return value._nullableOfInt32; + throw new System.InvalidOperationException("Inner value is not NullableOfInt32"); + } + + public bool TryGetNullableOfInt32(out int? value) + { + if (_variantId == NullableOfInt32Id) + { + value = _nullableOfInt32; + return true; + } + else + { + value = default; + return false; + } + } + + private const int StringId = 2; + private readonly string _string; + public bool IsString => _variantId == StringId; + public string AsString + { + get + { + if (_variantId == StringId) + return _string; + throw new System.InvalidOperationException("Inner value is not String"); + } + } + + public Result(string @string) + { + System.ArgumentNullException.ThrowIfNull(@string); + _variantId = StringId; + _string = @string; + } + + public static implicit operator Result(string @string) => new Result(@string); + public static explicit operator string(Result value) + { + if (value._variantId == StringId) + return value._string; + throw new System.InvalidOperationException("Inner value is not String"); + } + + public bool TryGetString([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out string value) + { + if (_variantId == StringId) + { + value = _string; + return true; + } + else + { + value = default; + return false; + } + } + + public TOut Match(global::System.Func matchNullableOfInt32, global::System.Func matchString) + { + if (_variantId == NullableOfInt32Id) + return matchNullableOfInt32(_nullableOfInt32); + if (_variantId == StringId) + return matchString(_string); + throw new System.InvalidOperationException("Inner type is unknown"); + } + + public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchNullableOfInt32, global::System.Func> matchString, global::System.Threading.CancellationToken ct) + { + if (_variantId == NullableOfInt32Id) + return await matchNullableOfInt32(_nullableOfInt32, ct).ConfigureAwait(false); + if (_variantId == StringId) + return await matchString(_string, ct).ConfigureAwait(false); + throw new System.InvalidOperationException("Inner type is unknown"); + } + + public void Switch(global::System.Action switchNullableOfInt32, global::System.Action switchString) + { + if (_variantId == NullableOfInt32Id) + { + switchNullableOfInt32(_nullableOfInt32); + return; + } + + if (_variantId == StringId) + { + switchString(_string); + return; + } + + throw new System.InvalidOperationException("Inner type is unknown"); + } + + public async global::System.Threading.Tasks.Task SwitchAsync(global::System.Func switchNullableOfInt32, global::System.Func switchString, global::System.Threading.CancellationToken ct) + { + if (_variantId == NullableOfInt32Id) + { + await switchNullableOfInt32(_nullableOfInt32, ct).ConfigureAwait(false); + return; + } + + if (_variantId == StringId) + { + await switchString(_string, ct).ConfigureAwait(false); + return; + } + + throw new System.InvalidOperationException("Inner type is unknown"); + } + + public global::System.Type ValueType + { + get + { + if (_variantId == NullableOfInt32Id) + return typeof(int?); + if (_variantId == StringId) + return typeof(string); + throw new System.InvalidOperationException("Inner type is unknown"); + } + } + + public override int GetHashCode() + { + if (_variantId == NullableOfInt32Id) + return _nullableOfInt32.GetHashCode(); + if (_variantId == StringId) + return _string.GetHashCode(); + throw new System.InvalidOperationException("Inner type is unknown"); + } + + public static bool operator ==(Result? left, Result? right) + { + return Equals(left, right); + } + + public static bool operator !=(Result? left, Result? right) + { + return !Equals(left, right); + } + + public bool Equals(Result? other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + if (ValueType != other.ValueType) + { + return false; + } + + if (_variantId == NullableOfInt32Id) + return System.Collections.Generic.EqualityComparer.Default.Equals(_nullableOfInt32, other._nullableOfInt32); + if (_variantId == StringId) + return System.Collections.Generic.EqualityComparer.Default.Equals(_string, other._string); + throw new System.InvalidOperationException("Inner type is unknown"); + } + + public override string ToString() + { + if (_variantId == NullableOfInt32Id) + return _nullableOfInt32.ToString(); + if (_variantId == StringId) + return _string.ToString(); + throw new System.InvalidOperationException("Inner type is unknown"); + } + + public override bool Equals(object? other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + if (other.GetType() != typeof(Result)) + { + return false; + } + + return Equals((Result)other); + } +} \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/NullableValueTests.UseAllowNullAttribute#UnionConverterAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/NullableValueTests.UseAllowNullAttribute#UnionConverterAttribute.g.verified.cs new file mode 100644 index 0000000..3e6fd2b --- /dev/null +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/NullableValueTests.UseAllowNullAttribute#UnionConverterAttribute.g.verified.cs @@ -0,0 +1,22 @@ +//HintName: UnionConverterAttribute.g.cs +#nullable enable +using System; +using System.Runtime.CompilerServices; + +namespace N.SourceGenerators.UnionTypes +{ + [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)] + sealed class UnionConverterAttribute : Attribute + { + public Type FromType { get; } + public Type ToType { get; } + public string? MethodName { get; } + + public UnionConverterAttribute(Type fromType, Type toType, string? methodName = null) + { + FromType = fromType; + ToType = toType; + MethodName = methodName; + } + } +} \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/NullableValueTests.UseAllowNullAttribute#UnionConverterFromAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/NullableValueTests.UseAllowNullAttribute#UnionConverterFromAttribute.g.verified.cs new file mode 100644 index 0000000..d740ef3 --- /dev/null +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/NullableValueTests.UseAllowNullAttribute#UnionConverterFromAttribute.g.verified.cs @@ -0,0 +1,22 @@ +//HintName: UnionConverterFromAttribute.g.cs +// +// This code was generated by https://github.com/Ne4to/N.SourceGenerators.UnionTypes +// Feel free to open an issue +// +#nullable enable +using System; +using System.Runtime.CompilerServices; + +namespace N.SourceGenerators.UnionTypes +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = true)] + sealed class UnionConverterFromAttribute : Attribute + { + public Type FromType { get; } + + public UnionConverterFromAttribute(Type fromType) + { + FromType = fromType; + } + } +} \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/NullableValueTests.UseAllowNullAttribute#UnionConverterToAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/NullableValueTests.UseAllowNullAttribute#UnionConverterToAttribute.g.verified.cs new file mode 100644 index 0000000..fae1e4d --- /dev/null +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/NullableValueTests.UseAllowNullAttribute#UnionConverterToAttribute.g.verified.cs @@ -0,0 +1,22 @@ +//HintName: UnionConverterToAttribute.g.cs +// +// This code was generated by https://github.com/Ne4to/N.SourceGenerators.UnionTypes +// Feel free to open an issue +// +#nullable enable +using System; +using System.Runtime.CompilerServices; + +namespace N.SourceGenerators.UnionTypes +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = true)] + sealed class UnionConverterToAttribute : Attribute + { + public Type ToType { get; } + + public UnionConverterToAttribute(Type toType) + { + ToType = toType; + } + } +} \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/NullableValueTests.UseAllowNullAttribute#UnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/NullableValueTests.UseAllowNullAttribute#UnionTypeAttribute.g.verified.cs new file mode 100644 index 0000000..c8f7fed --- /dev/null +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/NullableValueTests.UseAllowNullAttribute#UnionTypeAttribute.g.verified.cs @@ -0,0 +1,27 @@ +//HintName: UnionTypeAttribute.g.cs +// +// This code was generated by https://github.com/Ne4to/N.SourceGenerators.UnionTypes +// Feel free to open an issue +// +#nullable enable +using System; +using System.Runtime.CompilerServices; + +namespace N.SourceGenerators.UnionTypes +{ + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = true)] + internal sealed class UnionTypeAttribute : Attribute + { + public Type Type { get; } + public string? Alias { get; } + public int Order { get; } + public bool AllowNull { get; set; } + + public UnionTypeAttribute(Type type, string? alias = null, [CallerLineNumber] int order = 0) + { + Type = type; + Alias = alias; + Order = order; + } + } +} \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/TwoAssemblyTests.UnionConverterFromInOtherAssembly_0#DataAccessModel.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/TwoAssemblyTests.UnionConverterFromInOtherAssembly_0#DataAccessModel.g.verified.cs index 4ba167f..fa1a59b 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/TwoAssemblyTests.UnionConverterFromInOtherAssembly_0#DataAccessModel.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/TwoAssemblyTests.UnionConverterFromInOtherAssembly_0#DataAccessModel.g.verified.cs @@ -11,14 +11,14 @@ partial class DataAccessModel : System.IEquatable { private readonly int _variantId; private const int DataAccessModel1Id = 1; - private readonly global::DataAccess.DataAccessModel1? _dataAccessModel1; + private readonly global::DataAccess.DataAccessModel1 _dataAccessModel1; public bool IsDataAccessModel1 => _variantId == DataAccessModel1Id; public global::DataAccess.DataAccessModel1 AsDataAccessModel1 { get { if (_variantId == DataAccessModel1Id) - return _dataAccessModel1!; + return _dataAccessModel1; throw new System.InvalidOperationException("Inner value is not DataAccessModel1"); } } @@ -34,11 +34,11 @@ public DataAccessModel(global::DataAccess.DataAccessModel1 dataAccessModel1) public static explicit operator global::DataAccess.DataAccessModel1(DataAccessModel value) { if (value._variantId == DataAccessModel1Id) - return value._dataAccessModel1!; + return value._dataAccessModel1; throw new System.InvalidOperationException("Inner value is not DataAccessModel1"); } - public bool TryGetDataAccessModel1([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::DataAccess.DataAccessModel1? value) + public bool TryGetDataAccessModel1([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::DataAccess.DataAccessModel1 value) { if (_variantId == DataAccessModel1Id) { @@ -53,14 +53,14 @@ public bool TryGetDataAccessModel1([System.Diagnostics.CodeAnalysis.NotNullWhen( } private const int DataAccessModel2Id = 2; - private readonly global::DataAccess.DataAccessModel2? _dataAccessModel2; + private readonly global::DataAccess.DataAccessModel2 _dataAccessModel2; public bool IsDataAccessModel2 => _variantId == DataAccessModel2Id; public global::DataAccess.DataAccessModel2 AsDataAccessModel2 { get { if (_variantId == DataAccessModel2Id) - return _dataAccessModel2!; + return _dataAccessModel2; throw new System.InvalidOperationException("Inner value is not DataAccessModel2"); } } @@ -76,11 +76,11 @@ public DataAccessModel(global::DataAccess.DataAccessModel2 dataAccessModel2) public static explicit operator global::DataAccess.DataAccessModel2(DataAccessModel value) { if (value._variantId == DataAccessModel2Id) - return value._dataAccessModel2!; + return value._dataAccessModel2; throw new System.InvalidOperationException("Inner value is not DataAccessModel2"); } - public bool TryGetDataAccessModel2([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::DataAccess.DataAccessModel2? value) + public bool TryGetDataAccessModel2([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::DataAccess.DataAccessModel2 value) { if (_variantId == DataAccessModel2Id) { @@ -97,18 +97,18 @@ public bool TryGetDataAccessModel2([System.Diagnostics.CodeAnalysis.NotNullWhen( public TOut Match(global::System.Func matchDataAccessModel1, global::System.Func matchDataAccessModel2) { if (_variantId == DataAccessModel1Id) - return matchDataAccessModel1(_dataAccessModel1!); + return matchDataAccessModel1(_dataAccessModel1); if (_variantId == DataAccessModel2Id) - return matchDataAccessModel2(_dataAccessModel2!); + return matchDataAccessModel2(_dataAccessModel2); throw new System.InvalidOperationException("Inner type is unknown"); } public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchDataAccessModel1, global::System.Func> matchDataAccessModel2, global::System.Threading.CancellationToken ct) { if (_variantId == DataAccessModel1Id) - return await matchDataAccessModel1(_dataAccessModel1!, ct).ConfigureAwait(false); + return await matchDataAccessModel1(_dataAccessModel1, ct).ConfigureAwait(false); if (_variantId == DataAccessModel2Id) - return await matchDataAccessModel2(_dataAccessModel2!, ct).ConfigureAwait(false); + return await matchDataAccessModel2(_dataAccessModel2, ct).ConfigureAwait(false); throw new System.InvalidOperationException("Inner type is unknown"); } @@ -116,13 +116,13 @@ public void Switch(global::System.Action sw { if (_variantId == DataAccessModel1Id) { - switchDataAccessModel1(_dataAccessModel1!); + switchDataAccessModel1(_dataAccessModel1); return; } if (_variantId == DataAccessModel2Id) { - switchDataAccessModel2(_dataAccessModel2!); + switchDataAccessModel2(_dataAccessModel2); return; } @@ -133,13 +133,13 @@ public void Switch(global::System.Action sw { if (_variantId == DataAccessModel1Id) { - await switchDataAccessModel1(_dataAccessModel1!, ct).ConfigureAwait(false); + await switchDataAccessModel1(_dataAccessModel1, ct).ConfigureAwait(false); return; } if (_variantId == DataAccessModel2Id) { - await switchDataAccessModel2(_dataAccessModel2!, ct).ConfigureAwait(false); + await switchDataAccessModel2(_dataAccessModel2, ct).ConfigureAwait(false); return; } @@ -195,9 +195,9 @@ public bool Equals(DataAccessModel? other) } if (_variantId == DataAccessModel1Id) - return System.Collections.Generic.EqualityComparer.Default.Equals(_dataAccessModel1!, other._dataAccessModel1); + return System.Collections.Generic.EqualityComparer.Default.Equals(_dataAccessModel1, other._dataAccessModel1); if (_variantId == DataAccessModel2Id) - return System.Collections.Generic.EqualityComparer.Default.Equals(_dataAccessModel2!, other._dataAccessModel2); + return System.Collections.Generic.EqualityComparer.Default.Equals(_dataAccessModel2, other._dataAccessModel2); throw new System.InvalidOperationException("Inner type is unknown"); } diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/TwoAssemblyTests.UnionConverterFromInOtherAssembly_0#GenericUnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/TwoAssemblyTests.UnionConverterFromInOtherAssembly_0#GenericUnionTypeAttribute.g.verified.cs index 853ee82..e256764 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/TwoAssemblyTests.UnionConverterFromInOtherAssembly_0#GenericUnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/TwoAssemblyTests.UnionConverterFromInOtherAssembly_0#GenericUnionTypeAttribute.g.verified.cs @@ -9,8 +9,10 @@ namespace N.SourceGenerators.UnionTypes { - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] + [AttributeUsage(AttributeTargets.GenericParameter, Inherited = false, AllowMultiple = false)] internal sealed class GenericUnionTypeAttribute : Attribute { + public string? Alias { get; set; } + public bool AllowNull { get; set; } } } \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/TwoAssemblyTests.UnionConverterFromInOtherAssembly_0#UnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/TwoAssemblyTests.UnionConverterFromInOtherAssembly_0#UnionTypeAttribute.g.verified.cs index c9f95c1..c8f7fed 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/TwoAssemblyTests.UnionConverterFromInOtherAssembly_0#UnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/TwoAssemblyTests.UnionConverterFromInOtherAssembly_0#UnionTypeAttribute.g.verified.cs @@ -15,6 +15,7 @@ internal sealed class UnionTypeAttribute : Attribute public Type Type { get; } public string? Alias { get; } public int Order { get; } + public bool AllowNull { get; set; } public UnionTypeAttribute(Type type, string? alias = null, [CallerLineNumber] int order = 0) { diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/TwoAssemblyTests.UnionConverterFromInOtherAssembly_1#BusinessLogicModel.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/TwoAssemblyTests.UnionConverterFromInOtherAssembly_1#BusinessLogicModel.g.verified.cs index 59c0f7d..aabc295 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/TwoAssemblyTests.UnionConverterFromInOtherAssembly_1#BusinessLogicModel.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/TwoAssemblyTests.UnionConverterFromInOtherAssembly_1#BusinessLogicModel.g.verified.cs @@ -11,14 +11,14 @@ partial class BusinessLogicModel : System.IEquatable { private readonly int _variantId; private const int DataAccessModel1Id = 1; - private readonly global::DataAccess.DataAccessModel1? _dataAccessModel1; + private readonly global::DataAccess.DataAccessModel1 _dataAccessModel1; public bool IsDataAccessModel1 => _variantId == DataAccessModel1Id; public global::DataAccess.DataAccessModel1 AsDataAccessModel1 { get { if (_variantId == DataAccessModel1Id) - return _dataAccessModel1!; + return _dataAccessModel1; throw new System.InvalidOperationException("Inner value is not DataAccessModel1"); } } @@ -34,11 +34,11 @@ public BusinessLogicModel(global::DataAccess.DataAccessModel1 dataAccessModel1) public static explicit operator global::DataAccess.DataAccessModel1(BusinessLogicModel value) { if (value._variantId == DataAccessModel1Id) - return value._dataAccessModel1!; + return value._dataAccessModel1; throw new System.InvalidOperationException("Inner value is not DataAccessModel1"); } - public bool TryGetDataAccessModel1([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::DataAccess.DataAccessModel1? value) + public bool TryGetDataAccessModel1([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::DataAccess.DataAccessModel1 value) { if (_variantId == DataAccessModel1Id) { @@ -53,14 +53,14 @@ public bool TryGetDataAccessModel1([System.Diagnostics.CodeAnalysis.NotNullWhen( } private const int DataAccessModel2Id = 2; - private readonly global::DataAccess.DataAccessModel2? _dataAccessModel2; + private readonly global::DataAccess.DataAccessModel2 _dataAccessModel2; public bool IsDataAccessModel2 => _variantId == DataAccessModel2Id; public global::DataAccess.DataAccessModel2 AsDataAccessModel2 { get { if (_variantId == DataAccessModel2Id) - return _dataAccessModel2!; + return _dataAccessModel2; throw new System.InvalidOperationException("Inner value is not DataAccessModel2"); } } @@ -76,11 +76,11 @@ public BusinessLogicModel(global::DataAccess.DataAccessModel2 dataAccessModel2) public static explicit operator global::DataAccess.DataAccessModel2(BusinessLogicModel value) { if (value._variantId == DataAccessModel2Id) - return value._dataAccessModel2!; + return value._dataAccessModel2; throw new System.InvalidOperationException("Inner value is not DataAccessModel2"); } - public bool TryGetDataAccessModel2([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::DataAccess.DataAccessModel2? value) + public bool TryGetDataAccessModel2([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::DataAccess.DataAccessModel2 value) { if (_variantId == DataAccessModel2Id) { @@ -95,14 +95,14 @@ public bool TryGetDataAccessModel2([System.Diagnostics.CodeAnalysis.NotNullWhen( } private const int BusinessLogicModel1Id = 3; - private readonly global::BusinessLogic.BusinessLogicModel1? _businessLogicModel1; + private readonly global::BusinessLogic.BusinessLogicModel1 _businessLogicModel1; public bool IsBusinessLogicModel1 => _variantId == BusinessLogicModel1Id; public global::BusinessLogic.BusinessLogicModel1 AsBusinessLogicModel1 { get { if (_variantId == BusinessLogicModel1Id) - return _businessLogicModel1!; + return _businessLogicModel1; throw new System.InvalidOperationException("Inner value is not BusinessLogicModel1"); } } @@ -118,11 +118,11 @@ public BusinessLogicModel(global::BusinessLogic.BusinessLogicModel1 businessLogi public static explicit operator global::BusinessLogic.BusinessLogicModel1(BusinessLogicModel value) { if (value._variantId == BusinessLogicModel1Id) - return value._businessLogicModel1!; + return value._businessLogicModel1; throw new System.InvalidOperationException("Inner value is not BusinessLogicModel1"); } - public bool TryGetBusinessLogicModel1([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::BusinessLogic.BusinessLogicModel1? value) + public bool TryGetBusinessLogicModel1([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out global::BusinessLogic.BusinessLogicModel1 value) { if (_variantId == BusinessLogicModel1Id) { @@ -139,22 +139,22 @@ public bool TryGetBusinessLogicModel1([System.Diagnostics.CodeAnalysis.NotNullWh public TOut Match(global::System.Func matchDataAccessModel1, global::System.Func matchDataAccessModel2, global::System.Func matchBusinessLogicModel1) { if (_variantId == DataAccessModel1Id) - return matchDataAccessModel1(_dataAccessModel1!); + return matchDataAccessModel1(_dataAccessModel1); if (_variantId == DataAccessModel2Id) - return matchDataAccessModel2(_dataAccessModel2!); + return matchDataAccessModel2(_dataAccessModel2); if (_variantId == BusinessLogicModel1Id) - return matchBusinessLogicModel1(_businessLogicModel1!); + return matchBusinessLogicModel1(_businessLogicModel1); throw new System.InvalidOperationException("Inner type is unknown"); } public async global::System.Threading.Tasks.Task MatchAsync(global::System.Func> matchDataAccessModel1, global::System.Func> matchDataAccessModel2, global::System.Func> matchBusinessLogicModel1, global::System.Threading.CancellationToken ct) { if (_variantId == DataAccessModel1Id) - return await matchDataAccessModel1(_dataAccessModel1!, ct).ConfigureAwait(false); + return await matchDataAccessModel1(_dataAccessModel1, ct).ConfigureAwait(false); if (_variantId == DataAccessModel2Id) - return await matchDataAccessModel2(_dataAccessModel2!, ct).ConfigureAwait(false); + return await matchDataAccessModel2(_dataAccessModel2, ct).ConfigureAwait(false); if (_variantId == BusinessLogicModel1Id) - return await matchBusinessLogicModel1(_businessLogicModel1!, ct).ConfigureAwait(false); + return await matchBusinessLogicModel1(_businessLogicModel1, ct).ConfigureAwait(false); throw new System.InvalidOperationException("Inner type is unknown"); } @@ -162,19 +162,19 @@ public void Switch(global::System.Action sw { if (_variantId == DataAccessModel1Id) { - switchDataAccessModel1(_dataAccessModel1!); + switchDataAccessModel1(_dataAccessModel1); return; } if (_variantId == DataAccessModel2Id) { - switchDataAccessModel2(_dataAccessModel2!); + switchDataAccessModel2(_dataAccessModel2); return; } if (_variantId == BusinessLogicModel1Id) { - switchBusinessLogicModel1(_businessLogicModel1!); + switchBusinessLogicModel1(_businessLogicModel1); return; } @@ -185,19 +185,19 @@ public void Switch(global::System.Action sw { if (_variantId == DataAccessModel1Id) { - await switchDataAccessModel1(_dataAccessModel1!, ct).ConfigureAwait(false); + await switchDataAccessModel1(_dataAccessModel1, ct).ConfigureAwait(false); return; } if (_variantId == DataAccessModel2Id) { - await switchDataAccessModel2(_dataAccessModel2!, ct).ConfigureAwait(false); + await switchDataAccessModel2(_dataAccessModel2, ct).ConfigureAwait(false); return; } if (_variantId == BusinessLogicModel1Id) { - await switchBusinessLogicModel1(_businessLogicModel1!, ct).ConfigureAwait(false); + await switchBusinessLogicModel1(_businessLogicModel1, ct).ConfigureAwait(false); return; } @@ -257,11 +257,11 @@ public bool Equals(BusinessLogicModel? other) } if (_variantId == DataAccessModel1Id) - return System.Collections.Generic.EqualityComparer.Default.Equals(_dataAccessModel1!, other._dataAccessModel1); + return System.Collections.Generic.EqualityComparer.Default.Equals(_dataAccessModel1, other._dataAccessModel1); if (_variantId == DataAccessModel2Id) - return System.Collections.Generic.EqualityComparer.Default.Equals(_dataAccessModel2!, other._dataAccessModel2); + return System.Collections.Generic.EqualityComparer.Default.Equals(_dataAccessModel2, other._dataAccessModel2); if (_variantId == BusinessLogicModel1Id) - return System.Collections.Generic.EqualityComparer.Default.Equals(_businessLogicModel1!, other._businessLogicModel1); + return System.Collections.Generic.EqualityComparer.Default.Equals(_businessLogicModel1, other._businessLogicModel1); throw new System.InvalidOperationException("Inner type is unknown"); } diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/TwoAssemblyTests.UnionConverterFromInOtherAssembly_1#GenericUnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/TwoAssemblyTests.UnionConverterFromInOtherAssembly_1#GenericUnionTypeAttribute.g.verified.cs index 853ee82..e256764 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/TwoAssemblyTests.UnionConverterFromInOtherAssembly_1#GenericUnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/TwoAssemblyTests.UnionConverterFromInOtherAssembly_1#GenericUnionTypeAttribute.g.verified.cs @@ -9,8 +9,10 @@ namespace N.SourceGenerators.UnionTypes { - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)] + [AttributeUsage(AttributeTargets.GenericParameter, Inherited = false, AllowMultiple = false)] internal sealed class GenericUnionTypeAttribute : Attribute { + public string? Alias { get; set; } + public bool AllowNull { get; set; } } } \ No newline at end of file diff --git a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/TwoAssemblyTests.UnionConverterFromInOtherAssembly_1#UnionTypeAttribute.g.verified.cs b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/TwoAssemblyTests.UnionConverterFromInOtherAssembly_1#UnionTypeAttribute.g.verified.cs index c9f95c1..c8f7fed 100644 --- a/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/TwoAssemblyTests.UnionConverterFromInOtherAssembly_1#UnionTypeAttribute.g.verified.cs +++ b/tests/N.SourceGenerators.UnionTypes.Tests/Snapshots/TwoAssemblyTests.UnionConverterFromInOtherAssembly_1#UnionTypeAttribute.g.verified.cs @@ -15,6 +15,7 @@ internal sealed class UnionTypeAttribute : Attribute public Type Type { get; } public string? Alias { get; } public int Order { get; } + public bool AllowNull { get; set; } public UnionTypeAttribute(Type type, string? alias = null, [CallerLineNumber] int order = 0) {