diff --git a/Build.ps1 b/Build.ps1
index 449c3b11d42..c86c91c13ec 100644
--- a/Build.ps1
+++ b/Build.ps1
@@ -19,10 +19,14 @@ function BuildWith([string]$configuration)
exec { & dotnet build src/Vogen/Vogen.csproj -c $configuration -p Thorough=true -p RoslynVersion=roslyn4.4 --verbosity $verbosity}
exec { & dotnet build src/Vogen/Vogen.csproj -c $configuration -p Thorough=true -p RoslynVersion=roslyn4.6 --verbosity $verbosity}
exec { & dotnet build src/Vogen/Vogen.csproj -c $configuration -p Thorough=true -p RoslynVersion=roslyn4.8 --verbosity $verbosity}
+ exec { & dotnet build src/Vogen/Vogen.csproj -c $configuration -p Thorough=true -p RoslynVersion=roslyn4.11 --verbosity $verbosity}
+ exec { & dotnet build src/Vogen/Vogen.csproj -c $configuration -p Thorough=true -p RoslynVersion=roslyn4.12 --verbosity $verbosity}
exec { & dotnet build src/Vogen.CodeFixers/Vogen.CodeFixers.csproj -c $configuration -p Thorough=true -p RoslynVersion=roslyn4.4 --verbosity $verbosity}
exec { & dotnet build src/Vogen.CodeFixers/Vogen.CodeFixers.csproj -c $configuration -p Thorough=true -p RoslynVersion=roslyn4.6 --verbosity $verbosity}
exec { & dotnet build src/Vogen.CodeFixers/Vogen.CodeFixers.csproj -c $configuration -p Thorough=true -p RoslynVersion=roslyn4.8 --verbosity $verbosity}
+ exec { & dotnet build src/Vogen.CodeFixers/Vogen.CodeFixers.csproj -c $configuration -p Thorough=true -p RoslynVersion=roslyn4.11 --verbosity $verbosity}
+ exec { & dotnet build src/Vogen.CodeFixers/Vogen.CodeFixers.csproj -c $configuration -p Thorough=true -p RoslynVersion=roslyn4.12 --verbosity $verbosity}
}
function Get999VersionWithUniquePatch()
@@ -157,4 +161,3 @@ WriteStage("Finally, packing the release version into " + $artifacts)
exec { & dotnet pack src/Vogen.Pack/Vogen.Pack.csproj -c Release -o $artifacts --no-build --verbosity $verbosity }
WriteStage("Done! Package generated at " + $artifacts)
-
diff --git a/Directory.Build.targets b/Directory.Build.targets
index 2bd5e625ec2..d689dd99905 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -13,12 +13,15 @@
-
+
+
+
+
+
-
@@ -32,7 +35,6 @@
-
@@ -46,7 +48,6 @@
-
@@ -58,9 +59,8 @@
-
+
-
@@ -70,6 +70,19 @@
$(DefineConstants);CSHARP9_OR_GREATER;CSHARP10_OR_GREATER;CSHARP11_OR_GREATER;CSHARP12_OR_GREATER;CSHARP13_OR_GREATER
$(NoWarn);CS0618
+
+
+
+
+
+
+
+
+
+ $(DefineConstants);ROSLYN4_12;ROSLYN_4_2_OR_GREATER;ROSLYN_4_4_OR_GREATER;ROSLYN_4_5_OR_GREATER;ROSLYN_4_6_OR_GREATER;ROSLYN_4_8_OR_GREATER;ROSLYN_4_10_OR_GREATER;ROSLYN_4_12_OR_GREATER
+ $(DefineConstants);CSHARP9_OR_GREATER;CSHARP10_OR_GREATER;CSHARP11_OR_GREATER;CSHARP12_OR_GREATER;CSHARP13_OR_GREATER
+ $(NoWarn);CS0618
+
diff --git a/src/Vogen.Pack/Vogen.Pack.csproj b/src/Vogen.Pack/Vogen.Pack.csproj
index 7158a532fb4..8ca6f3a84d2 100644
--- a/src/Vogen.Pack/Vogen.Pack.csproj
+++ b/src/Vogen.Pack/Vogen.Pack.csproj
@@ -58,12 +58,17 @@
-
+
+
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/src/Vogen/BuildWorkItems.cs b/src/Vogen/BuildWorkItems.cs
index e8504a452d4..7a501afe0ec 100644
--- a/src/Vogen/BuildWorkItems.cs
+++ b/src/Vogen/BuildWorkItems.cs
@@ -96,6 +96,9 @@ internal static class BuildWorkItems
UserProvidedOverloads userProvidedOverloads =
DiscoverUserProvidedOverloads.Discover(voSymbolInformation, underlyingType);
+ UserProvidedPartials userProvidedPartials =
+ DiscoverUserProvidedPartials.Discover(voSymbolInformation, underlyingType);
+
ThrowIfAnyToStringOverrideOnRecordIsUnsealed(target, context, userProvidedOverloads.ToStringOverloads);
MethodDeclarationSyntax? validateMethod = null;
@@ -150,6 +153,7 @@ RecordDeclarationSyntax rds when rds.IsKind(SyntaxKind.RecordStructDeclaration)
Config = config,
UserProvidedOverloads = userProvidedOverloads,
+ UserProvidedPartials = userProvidedPartials,
UnderlyingType = underlyingType,
ValidateMethod = validateMethod,
diff --git a/src/Vogen/DiscoverUserProvidedPartials.cs b/src/Vogen/DiscoverUserProvidedPartials.cs
new file mode 100644
index 00000000000..e96e0b24f2e
--- /dev/null
+++ b/src/Vogen/DiscoverUserProvidedPartials.cs
@@ -0,0 +1,47 @@
+using Microsoft.CodeAnalysis;
+using System.Linq;
+
+namespace Vogen;
+
+internal class DiscoverUserProvidedPartials
+{
+ public static UserProvidedPartials Discover(INamedTypeSymbol vo, INamedTypeSymbol underlyingType) =>
+ new()
+ {
+ PartialValue = TryGetPartialProperty(vo, "Value"),
+ PartialFrom = TryGetPartialMethod(vo, "From", [underlyingType]),
+ PartialBoolTryFrom = TryGetPartialMethod(vo, "TryFrom", [underlyingType, vo]),
+ PartialErrorTryFrom = TryGetPartialMethod(vo, "TryFrom", [underlyingType]),
+ };
+
+ private static UserProvidedPartial? TryGetPartialProperty(ITypeSymbol vo, string propertyName)
+ {
+#if ROSLYN_4_12_OR_GREATER
+ var property = vo.GetMembers(propertyName)
+ .OfType()
+ .SingleOrDefault(x => x.IsPartialDefinition);
+
+ if (property is null)
+ return null;
+
+ return new(property.DeclaredAccessibility);
+#else
+ return null;
+#endif
+ }
+
+ private static UserProvidedPartial? TryGetPartialMethod(ITypeSymbol vo, string methodName, ITypeSymbol[] parameterTypes)
+ {
+ var method = vo.GetMembers(methodName)
+ .OfType()
+ .Where(x => x.IsPartialDefinition)
+ .SingleOrDefault(x =>
+ x.Parameters.Select(y => y.Type).SequenceEqual(parameterTypes, SymbolEqualityComparer.Default)
+ );
+
+ if (method is null)
+ return null;
+
+ return new(method.DeclaredAccessibility);
+ }
+}
\ No newline at end of file
diff --git a/src/Vogen/GenerateCodeForTryFrom.cs b/src/Vogen/GenerateCodeForTryFrom.cs
index ad4f30bb55c..e58c8c495f4 100644
--- a/src/Vogen/GenerateCodeForTryFrom.cs
+++ b/src/Vogen/GenerateCodeForTryFrom.cs
@@ -34,7 +34,7 @@ private static string Generate(VoWorkItem item, SyntaxToken className, string it
/// An instance of the value object.
/// True if the value object can be built, otherwise false.
#pragma warning disable CS8767 // Nullability of reference types in type of parameter doesn't match implicitly implemented member because of nullability attributes.
- public static bool TryFrom({{Util.GenerateNotNullWhenTrueAttribute()}} {{itemUnderlyingType}}{{underlyingNullable}} value, {{Util.GenerateMaybeNullWhenFalse()}} out {{className}} vo)
+ {{Util.GenerateMethodModifiers(Accessibility.Public, ["static"], item.UserProvidedPartials.PartialBoolTryFrom)}} bool TryFrom({{Util.GenerateNotNullWhenTrueAttribute()}} {{itemUnderlyingType}}{{underlyingNullable}} value, {{Util.GenerateMaybeNullWhenFalse()}} out {{className}} vo)
#pragma warning restore CS8767 // Nullability of reference types in type of parameter doesn't match implicitly implemented member because of nullability attributes.
{
{{GenerateNullCheckAndReturnFalseIfNeeded(item)}}
@@ -59,7 +59,7 @@ public static bool TryFrom({{Util.GenerateNotNullWhenTrueAttribute()}} {{itemUnd
///
/// The primitive value.
/// A containing either the value object, or an error.
- public static Vogen.ValueObjectOrError<{{className}}> TryFrom({{itemUnderlyingType}} value)
+ {{Util.GenerateMethodModifiers(Accessibility.Public, ["static"], item.UserProvidedPartials.PartialErrorTryFrom)}} Vogen.ValueObjectOrError<{{className}}> TryFrom({{itemUnderlyingType}} value)
{
{{GenerateNullCheckAndReturnErrorIfNeeded(className, item)}}
diff --git a/src/Vogen/Generators/ClassGenerator.cs b/src/Vogen/Generators/ClassGenerator.cs
index e0364dede20..7082815f20b 100644
--- a/src/Vogen/Generators/ClassGenerator.cs
+++ b/src/Vogen/Generators/ClassGenerator.cs
@@ -49,7 +49,7 @@ string GenerateCode() => $@"
private {readonlyForValueAndIsInitialized} {itemUnderlyingType}{underlyingNullAnnotation} _value;
{Util.GenerateCommentForValueProperty(item)}
- public {itemUnderlyingType} Value
+ {Util.GenerateMethodModifiers(Accessibility.Public, [], item.UserProvidedPartials.PartialValue)} {itemUnderlyingType} Value
{{
[global::System.Diagnostics.DebuggerStepThroughAttribute]
[global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
@@ -90,7 +90,7 @@ string GenerateCode() => $@"
/// The underlying type.
/// An instance of this type.
[global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
- public static {wrapperName} From({itemUnderlyingType} value)
+ {Util.GenerateMethodModifiers(Accessibility.Public, ["static"], item.UserProvidedPartials.PartialFrom)} {wrapperName} From({itemUnderlyingType} value)
{{
{Util.GenerateNullCheckAndThrowIfNeeded(item, generateReturnDefault: true)}
diff --git a/src/Vogen/Generators/RecordClassGenerator.cs b/src/Vogen/Generators/RecordClassGenerator.cs
index 21053b8ef2d..8ecea72cda7 100644
--- a/src/Vogen/Generators/RecordClassGenerator.cs
+++ b/src/Vogen/Generators/RecordClassGenerator.cs
@@ -48,7 +48,7 @@ string GenerateCode() => $@"
private {readonlyForValueAndIsInitialized} {itemUnderlyingType}{underlyingNullAnnotation} _value;
{Util.GenerateCommentForValueProperty(item)}
- public {itemUnderlyingType} Value
+ {Util.GenerateMethodModifiers(Accessibility.Public, [], item.UserProvidedPartials.PartialValue)} {itemUnderlyingType} Value
{{
[global::System.Diagnostics.DebuggerStepThroughAttribute]
[global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
@@ -100,7 +100,7 @@ string GenerateCode() => $@"
/// The underlying type.
/// An instance of this type.
[global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
- public static {wrapperName} From({itemUnderlyingType} value)
+ {Util.GenerateMethodModifiers(Accessibility.Public, ["static"], item.UserProvidedPartials.PartialFrom)} {wrapperName} From({itemUnderlyingType} value)
{{
{Util.GenerateNullCheckAndThrowIfNeeded(item, generateReturnDefault: true)}
diff --git a/src/Vogen/Generators/RecordStructGenerator.cs b/src/Vogen/Generators/RecordStructGenerator.cs
index 70bb861e263..e39e8658261 100644
--- a/src/Vogen/Generators/RecordStructGenerator.cs
+++ b/src/Vogen/Generators/RecordStructGenerator.cs
@@ -48,7 +48,7 @@ string GenerateCode() => $@"
private {readonlyForValueAndIsInitialized} {itemUnderlyingType}{underlyingNullAnnotation} _value;
{Util.GenerateCommentForValueProperty(item)}
- public readonly {itemUnderlyingType} Value
+ {Util.GenerateMethodModifiers(Accessibility.Public, ["readonly"], item.UserProvidedPartials.PartialValue)} {itemUnderlyingType} Value
{{
[global::System.Diagnostics.DebuggerStepThroughAttribute]
[global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
@@ -88,7 +88,7 @@ public readonly {itemUnderlyingType} Value
/// The underlying type.
/// An instance of this type.
[global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
- public static {wrapperName} From({itemUnderlyingType} value)
+ {Util.GenerateMethodModifiers(Accessibility.Public, ["static"], item.UserProvidedPartials.PartialFrom)} {wrapperName} From({itemUnderlyingType} value)
{{
{Util.GenerateNullCheckAndThrowIfNeeded(item, generateReturnDefault: true)}
diff --git a/src/Vogen/Generators/StructGenerator.cs b/src/Vogen/Generators/StructGenerator.cs
index 47ca7b8d6c3..aee3c6be116 100644
--- a/src/Vogen/Generators/StructGenerator.cs
+++ b/src/Vogen/Generators/StructGenerator.cs
@@ -49,7 +49,7 @@ string GenerateCode() => $@"
private {readonlyForValueAndIsInitialized} {itemUnderlyingType}{underlyingNullAnnotation} _value;
{Util.GenerateCommentForValueProperty(item)}
- public readonly {itemUnderlyingType} Value
+ {Util.GenerateMethodModifiers(Accessibility.Public, ["readonly"], item.UserProvidedPartials.PartialValue)} {itemUnderlyingType} Value
{{
[global::System.Diagnostics.DebuggerStepThroughAttribute]
[global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
@@ -81,7 +81,7 @@ public readonly {itemUnderlyingType} Value
/// The underlying type.
/// An instance of this type.
[global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
- public static {wrapperName} From({itemUnderlyingType} value)
+ {Util.GenerateMethodModifiers(Accessibility.Public, ["static"], item.UserProvidedPartials.PartialFrom)} {wrapperName} From({itemUnderlyingType} value)
{{
{Util.GenerateNullCheckAndThrowIfNeeded(item, generateReturnDefault: true)}
diff --git a/src/Vogen/Util.cs b/src/Vogen/Util.cs
index a2ec6a7a283..bae8788fdb7 100644
--- a/src/Vogen/Util.cs
+++ b/src/Vogen/Util.cs
@@ -5,6 +5,7 @@
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
+using System.Collections.Generic;
using Vogen.Generators.Conversions;
using Vogen.Types;
@@ -29,6 +30,37 @@ public static string GenerateNullCheckAndThrowIfNeeded(VoWorkItem voWorkItem, bo
""";
}
+ public static string GenerateMethodModifiers(
+ Accessibility defaultAccessibility,
+ IEnumerable otherModifers,
+ UserProvidedPartial? userProvidedPartial
+ )
+ {
+#pragma warning disable CS8524 // A switch on enum handles all the values
+ var accessModifiers = (userProvidedPartial?.DeclaredAccessibility ?? defaultAccessibility) switch
+#pragma warning restore CS8524
+ {
+ Accessibility.NotApplicable => string.Empty,
+ Accessibility.Private => "private",
+ Accessibility.ProtectedAndInternal => "private protected",
+ Accessibility.Protected => "protected",
+ Accessibility.Internal => "internal",
+ Accessibility.ProtectedOrInternal => "protected internal",
+ Accessibility.Public => "public",
+ };
+
+ var modifiers = new List { accessModifiers };
+
+ modifiers.AddRange(otherModifers);
+
+ if (userProvidedPartial is not null)
+ {
+ modifiers.Add("partial");
+ }
+
+ return string.Join(" ", modifiers);
+ }
+
public static string EscapeTypeNameForTripleSlashComment(string typeName) =>
typeName.Replace("<", "{").Replace(">", "}");
diff --git a/src/Vogen/VoWorkItem.cs b/src/Vogen/VoWorkItem.cs
index 4f9d05d1202..db6a7abc95a 100644
--- a/src/Vogen/VoWorkItem.cs
+++ b/src/Vogen/VoWorkItem.cs
@@ -80,6 +80,7 @@ private bool SeeIfAssignableFromString()
public string AccessibilityKeyword { get; init; } = "public";
public required UserProvidedOverloads UserProvidedOverloads { get; init; }
+ public required UserProvidedPartials UserProvidedPartials { get; init; }
public required INamedTypeSymbol WrapperType { get; init; }
@@ -140,3 +141,14 @@ public class UserProvidedOverloads
public required UserProvidedTryFormatMethods TryFormatMethods { get; init; }
}
+public record UserProvidedPartial(
+ Accessibility DeclaredAccessibility
+);
+
+public class UserProvidedPartials
+{
+ public required UserProvidedPartial? PartialValue { get; init; }
+ public required UserProvidedPartial? PartialFrom { get; init; }
+ public required UserProvidedPartial? PartialBoolTryFrom { get; init; }
+ public required UserProvidedPartial? PartialErrorTryFrom { get; init; }
+}
diff --git a/tests/Shared/ProjectBuilder.cs b/tests/Shared/ProjectBuilder.cs
index 3bdf538cef8..f8c037be6d2 100644
--- a/tests/Shared/ProjectBuilder.cs
+++ b/tests/Shared/ProjectBuilder.cs
@@ -347,7 +347,8 @@ internal static class IsExternalInit {}
}
else
{
- initialDiags = compilation.GetDiagnostics();
+ initialDiags = compilation.GetDiagnostics()
+ .RemoveAll(x => x.Id is "CS8795"); // allow partial method implementation in generated code
}
//var initialDiags = compilation.GetDiagnostics();
diff --git a/tests/SnapshotTests/InternalDiagnostics/snapshots/snap-v8.0/InternalDiagnosticsTests.It_writes_diagnostics_if___ProduceDiagnostics_class_is_present_in_the_Vogen_namespace.verified.txt b/tests/SnapshotTests/InternalDiagnostics/snapshots/snap-v8.0/InternalDiagnosticsTests.It_writes_diagnostics_if___ProduceDiagnostics_class_is_present_in_the_Vogen_namespace.verified.txt
index 475642a7c29..eb767b363ba 100644
--- a/tests/SnapshotTests/InternalDiagnostics/snapshots/snap-v8.0/InternalDiagnosticsTests.It_writes_diagnostics_if___ProduceDiagnostics_class_is_present_in_the_Vogen_namespace.verified.txt
+++ b/tests/SnapshotTests/InternalDiagnostics/snapshots/snap-v8.0/InternalDiagnosticsTests.It_writes_diagnostics_if___ProduceDiagnostics_class_is_present_in_the_Vogen_namespace.verified.txt
@@ -641,7 +641,7 @@ private readonly global::System.Diagnostics.StackTrace _stackTrace = null!;
/*
Generator count: 1
-LanguageVersion: CSharp12
+LanguageVersion: CSharp13
User provided global config
===========
diff --git a/tests/SnapshotTests/PartialMethods/PartialMethodsTests.cs b/tests/SnapshotTests/PartialMethods/PartialMethodsTests.cs
new file mode 100644
index 00000000000..14b486bc515
--- /dev/null
+++ b/tests/SnapshotTests/PartialMethods/PartialMethodsTests.cs
@@ -0,0 +1,52 @@
+using Shared;
+using System.Threading.Tasks;
+using Vogen;
+
+namespace SnapshotTests.PartialMethods;
+
+public sealed class PartialMethodsTests
+{
+ [Fact]
+ public Task Uses_method_partial_modifier_to_change_visibility()
+ {
+ const string source = """
+ namespace Whatever;
+
+ using Vogen;
+
+ [ValueObject]
+ public partial class MyVo
+ {
+ private static partial MyVo From(string value);
+ internal static partial bool TryFrom(string value, out MyVo result);
+ private protected static partial ValueObjectOrError TryFrom(string value);
+ }
+ """;
+
+ return new SnapshotRunner()
+ .WithSource(source)
+ .RunOn(TargetFramework.Net9_0);
+ }
+
+ [Fact]
+ public Task Uses_method_partial_modifier_to_add_attribute()
+ {
+ const string source = """
+ namespace Whatever;
+
+ using System;
+ using Vogen;
+
+ [ValueObject]
+ public partial struct MyVo
+ {
+ [Obsolete("Let's try an attribute")]
+ public static partial MyVo From(string value);
+ }
+ """;
+
+ return new SnapshotRunner()
+ .WithSource(source)
+ .RunOn(TargetFramework.Net9_0);
+ }
+}
\ No newline at end of file
diff --git a/tests/SnapshotTests/PartialMethods/snapshots/snap-v9.0/PartialMethodsTests.Uses_method_partial_modifier_to_add_attribute.verified.txt b/tests/SnapshotTests/PartialMethods/snapshots/snap-v9.0/PartialMethodsTests.Uses_method_partial_modifier_to_add_attribute.verified.txt
new file mode 100644
index 00000000000..058550022ea
--- /dev/null
+++ b/tests/SnapshotTests/PartialMethods/snapshots/snap-v9.0/PartialMethodsTests.Uses_method_partial_modifier_to_add_attribute.verified.txt
@@ -0,0 +1,478 @@
+[
+// ------------------------------------------------------------------------------
+//
+// This code was generated by a source generator named Vogen (https://github.com/SteveDunn/Vogen)
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+// ------------------------------------------------------------------------------
+// Suppress warnings about [Obsolete] member usage in generated code.
+#pragma warning disable CS0618
+// Suppress warnings for 'Override methods on comparable types'.
+#pragma warning disable CA1036
+// Suppress Error MA0097 : A class that implements IComparable or IComparable should override comparison operators
+#pragma warning disable MA0097
+// Suppress warning for 'The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.'
+// The generator copies signatures from the BCL, e.g. for `TryParse`, and some of those have nullable annotations.
+#pragma warning disable CS8669, CS8632
+#pragma warning disable CS8604 // Possible null reference argument.
+
+// Suppress warnings about CS1591: Missing XML comment for publicly visible type or member 'Type_or_Member'
+#pragma warning disable CS1591
+namespace generator
+{
+ [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Vogen", "1.0.0.0")]
+ public class VogenTypesFactory : global::System.Text.Json.Serialization.JsonConverterFactory
+ {
+ public VogenTypesFactory()
+ {
+ }
+
+ private static readonly global::System.Collections.Generic.Dictionary> _lookup = new global::System.Collections.Generic.Dictionary>
+ {
+ {
+ typeof(global::Whatever.MyVo),
+ new global::System.Lazy(() => new global::Whatever.MyVo.MyVoSystemTextJsonConverter())
+ }
+ };
+ public override bool CanConvert(global::System.Type typeToConvert) => _lookup.ContainsKey(typeToConvert);
+ public override global::System.Text.Json.Serialization.JsonConverter CreateConverter(global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) => _lookup[typeToConvert].Value;
+ }
+}
+
+// ------------------------------------------------------------------------------
+//
+// This code was generated by a source generator named Vogen (https://github.com/SteveDunn/Vogen)
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+// ------------------------------------------------------------------------------
+// Suppress warnings about [Obsolete] member usage in generated code.
+#pragma warning disable CS0618
+// Suppress warnings for 'Override methods on comparable types'.
+#pragma warning disable CA1036
+// Suppress Error MA0097 : A class that implements IComparable or IComparable should override comparison operators
+#pragma warning disable MA0097
+// Suppress warning for 'The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.'
+// The generator copies signatures from the BCL, e.g. for `TryParse`, and some of those have nullable annotations.
+#pragma warning disable CS8669, CS8632
+#pragma warning disable CS8604 // Possible null reference argument.
+
+// Suppress warnings about CS1591: Missing XML comment for publicly visible type or member 'Type_or_Member'
+#pragma warning disable CS1591
+namespace Whatever
+{
+ [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Vogen", "1.0.0.0")]
+ [global::System.Text.Json.Serialization.JsonConverter(typeof(MyVoSystemTextJsonConverter))]
+ [global::System.ComponentModel.TypeConverter(typeof(MyVoTypeConverter))]
+ [global::System.Diagnostics.DebuggerTypeProxyAttribute(typeof(MyVoDebugView))]
+ [global::System.Diagnostics.DebuggerDisplayAttribute("Underlying type: System.String, Value = { _value }")]
+ // ReSharper disable once UnusedType.Global
+ public partial struct MyVo : global::System.IEquatable, global::System.IEquatable, global::System.IComparable, global::System.IComparable, global::System.IParsable
+ {
+#if DEBUG
+private readonly global::System.Diagnostics.StackTrace _stackTrace = null!;
+#endif
+#if !VOGEN_NO_VALIDATION
+ private readonly global::System.Boolean _isInitialized;
+#endif
+ private readonly System.String _value;
+ ///
+ /// Gets the underlying value if set, otherwise a is thrown.
+ ///
+ public readonly System.String Value
+ {
+ [global::System.Diagnostics.DebuggerStepThroughAttribute]
+ [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+ get
+ {
+ EnsureInitialized();
+ return _value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerStepThroughAttribute]
+ [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
+ public MyVo()
+ {
+#if DEBUG
+ _stackTrace = new global::System.Diagnostics.StackTrace();
+#endif
+#if !VOGEN_NO_VALIDATION
+ _isInitialized = false;
+#endif
+ _value = default;
+ }
+
+ [global::System.Diagnostics.DebuggerStepThroughAttribute]
+ private MyVo(System.String value)
+ {
+ _value = value;
+#if !VOGEN_NO_VALIDATION
+ _isInitialized = true;
+#endif
+#if DEBUG
+ _stackTrace = null;
+#endif
+ }
+
+ ///
+ /// Builds an instance from the provided underlying type.
+ ///
+ /// The underlying type.
+ /// An instance of this type.
+ [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+ public static partial MyVo From(System.String value)
+ {
+ if (value is null)
+ {
+ ThrowHelper.ThrowWhenCreatedWithNull();
+ return default !;
+ }
+
+ return new MyVo(value);
+ }
+
+ ///
+ /// Tries to build an instance from the provided underlying type.
+ /// If a normalization method is provided, it will be called.
+ /// If validation is provided, and it fails, false will be returned.
+ ///
+ /// The underlying type.
+ /// An instance of the value object.
+ /// True if the value object can be built, otherwise false.
+
+#pragma warning disable CS8767 // Nullability of reference types in type of parameter doesn't match implicitly implemented member because of nullability attributes.
+
+ public static bool TryFrom(
+#if NETCOREAPP3_0_OR_GREATER
+[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
+#endif
+ System.String value,
+#if NETCOREAPP3_0_OR_GREATER
+[global::System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)]
+#endif
+ out MyVo vo)
+#pragma warning restore CS8767 // Nullability of reference types in type of parameter doesn't match implicitly implemented member because of nullability attributes.
+
+ {
+ if (value is null)
+ {
+ vo = default;
+ return false;
+ }
+
+ vo = new MyVo(value);
+ return true;
+ }
+
+ ///
+ /// Tries to build an instance from the provided underlying value.
+ /// If a normalization method is provided, it will be called.
+ /// If validation is provided, and it fails, an error will be returned.
+ ///
+ /// The primitive value.
+ /// A containing either the value object, or an error.
+ public static Vogen.ValueObjectOrError TryFrom(System.String value)
+ {
+ if (value is null)
+ {
+ return new Vogen.ValueObjectOrError(Vogen.Validation.Invalid("The value provided was null"));
+ }
+
+ return new Vogen.ValueObjectOrError(new MyVo(value));
+ }
+
+ [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+#if VOGEN_NO_VALIDATION
+#pragma warning disable CS8775
+ public readonly bool IsInitialized() => true;
+#pragma warning restore CS8775
+#else
+ public readonly bool IsInitialized() => _isInitialized;
+#endif
+ public static explicit operator MyVo(System.String value) => From(value);
+ public static explicit operator System.String(MyVo value) => value.Value;
+ // only called internally when something has been deserialized into
+ // its primitive type.
+ private static MyVo __Deserialize(System.String value)
+ {
+ if (value is null)
+ {
+ ThrowHelper.ThrowWhenCreatedWithNull();
+ return default !;
+ }
+
+ return new MyVo(value);
+ }
+
+ public readonly global::System.Boolean Equals(MyVo other)
+ {
+ // It's possible to create uninitialized instances via converters such as EfCore (HasDefaultValue), which call Equals.
+ // We treat anything uninitialized as not equal to anything, even other uninitialized instances of this type.
+ if (!IsInitialized() || !other.IsInitialized())
+ return false;
+ return global::System.Collections.Generic.EqualityComparer.Default.Equals(Value, other.Value);
+ }
+
+ public global::System.Boolean Equals(MyVo other, global::System.Collections.Generic.IEqualityComparer comparer)
+ {
+ return comparer.Equals(this, other);
+ }
+
+ public readonly global::System.Boolean Equals(System.String primitive)
+ {
+ return Value.Equals(primitive);
+ }
+
+ public readonly global::System.Boolean Equals(System.String primitive, global::System.StringComparer comparer)
+ {
+ return comparer.Equals(Value, primitive);
+ }
+
+ public readonly override global::System.Boolean Equals(global::System.Object obj)
+ {
+ return obj is MyVo && Equals((MyVo)obj);
+ }
+
+ public static global::System.Boolean operator ==(MyVo left, MyVo right) => left.Equals(right);
+ public static global::System.Boolean operator !=(MyVo left, MyVo right) => !(left == right);
+ public static global::System.Boolean operator ==(MyVo left, System.String right) => left.Value.Equals(right);
+ public static global::System.Boolean operator ==(System.String left, MyVo right) => right.Value.Equals(left);
+ public static global::System.Boolean operator !=(System.String left, MyVo right) => !(left == right);
+ public static global::System.Boolean operator !=(MyVo left, System.String right) => !(left == right);
+ public int CompareTo(MyVo other) => Value.CompareTo(other.Value);
+ public int CompareTo(object other)
+ {
+ if (other is null)
+ return 1;
+ if (other is MyVo x)
+ return CompareTo(x);
+ ThrowHelper.ThrowArgumentException("Cannot compare to object as it is not of type MyVo", nameof(other));
+ return 0;
+ }
+
+ ///
+ ///
+ ///
+ /// True if the value passes any validation (after running any optional normalization).
+ ///
+ public static global::System.Boolean TryParse(
+#if NETCOREAPP3_0_OR_GREATER
+[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
+#endif
+ global::System.String s, global::System.IFormatProvider provider,
+#if NETCOREAPP3_0_OR_GREATER
+[global::System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)]
+#endif
+ out MyVo result)
+ {
+ if (s is null)
+ {
+ result = default;
+ return false;
+ }
+
+ result = new MyVo(s);
+ return true;
+ }
+
+ ///
+ ///
+ ///
+ /// The value created via the method.
+ ///
+ /// Thrown when the value can be parsed, but is not valid.
+ public static MyVo Parse(global::System.String s, global::System.IFormatProvider provider)
+ {
+ return From(s);
+ }
+
+#nullable disable
+#nullable restore
+ public readonly override global::System.Int32 GetHashCode()
+ {
+ return global::System.Collections.Generic.EqualityComparer.Default.GetHashCode(Value);
+ }
+
+ ///
+ public override global::System.String ToString() => IsInitialized() ? Value.ToString() ?? "" : "[UNINITIALIZED]";
+ ///
+ public global::System.String ToString(global::System.IFormatProvider provider) => IsInitialized() ? Value.ToString(provider) ?? "" : "[UNINITIALIZED]";
+ [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+ private readonly void EnsureInitialized()
+ {
+ if (!IsInitialized())
+ {
+#if DEBUG
+ ThrowHelper.ThrowWhenNotInitialized(_stackTrace);
+#else
+ ThrowHelper.ThrowWhenNotInitialized();
+#endif
+ }
+ }
+
+#nullable disable
+ ///
+ /// Converts a MyVo to or from JSON.
+ ///
+ public partial class MyVoSystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ public override MyVo Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+ return DeserializeJson(reader.GetString());
+ }
+
+ public override void Write(System.Text.Json.Utf8JsonWriter writer, MyVo value, global::System.Text.Json.JsonSerializerOptions options)
+ {
+ writer.WriteStringValue(value.Value);
+ }
+
+#if NET6_0_OR_GREATER
+ public override MyVo ReadAsPropertyName(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+ return DeserializeJson(reader.GetString());
+ }
+
+ public override void WriteAsPropertyName(System.Text.Json.Utf8JsonWriter writer, MyVo value, global::System.Text.Json.JsonSerializerOptions options)
+ {
+ writer.WritePropertyName(value.Value);
+ }
+#endif
+#if NETCOREAPP3_0_OR_GREATER
+ [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute]
+#endif
+ private static void ThrowJsonExceptionWhenValidationFails(Vogen.Validation validation)
+ {
+ var e = ThrowHelper.CreateValidationException(validation);
+ throw new global::System.Text.Json.JsonException(null, e);
+ }
+
+ private static void ThrowJsonExceptionWhenNull(System.String value)
+ {
+ if (value == null)
+ {
+ var e = ThrowHelper.CreateCannotBeNullException();
+ throw new global::System.Text.Json.JsonException(null, e);
+ }
+ }
+
+ private static MyVo DeserializeJson(System.String value)
+ {
+ ThrowJsonExceptionWhenNull(value);
+ return new MyVo(value);
+ }
+ }
+
+#nullable restore
+#nullable disable
+ class MyVoTypeConverter : global::System.ComponentModel.TypeConverter
+ {
+ public override global::System.Boolean CanConvertFrom(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Type sourceType)
+ {
+ return sourceType == typeof(global::System.String) || base.CanConvertFrom(context, sourceType);
+ }
+
+ public override global::System.Object ConvertFrom(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Globalization.CultureInfo culture, global::System.Object value)
+ {
+ var stringValue = value as global::System.String;
+ if (stringValue != null)
+ {
+ return MyVo.__Deserialize(stringValue);
+ }
+
+ return base.ConvertFrom(context, culture, value);
+ }
+
+ public override bool CanConvertTo(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Type sourceType)
+ {
+ return sourceType == typeof(global::System.String) || base.CanConvertTo(context, sourceType);
+ }
+
+ public override object ConvertTo(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Globalization.CultureInfo culture, global::System.Object value, global::System.Type destinationType)
+ {
+ if (value is MyVo idValue)
+ {
+ if (destinationType == typeof(global::System.String))
+ {
+ return idValue.Value;
+ }
+ }
+
+ return base.ConvertTo(context, culture, value, destinationType);
+ }
+ }
+
+#nullable restore
+#nullable disable
+ internal sealed class MyVoDebugView
+ {
+ private readonly MyVo _t;
+ MyVoDebugView(MyVo t)
+ {
+ _t = t;
+ }
+
+ public global::System.Boolean IsInitialized => _t.IsInitialized();
+ public global::System.String UnderlyingType => "System.String";
+ public global::System.String Value => _t.IsInitialized() ? _t._value.ToString() : "[not initialized]";
+#if DEBUG
+ public global::System.String CreatedWith => _t._stackTrace.ToString() ?? "the From method";
+#endif
+ public global::System.String Conversions => @"Default";
+ }
+
+#nullable restore
+ static class ThrowHelper
+ {
+#if NETCOREAPP3_0_OR_GREATER
+ [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute]
+#endif
+ internal static void ThrowInvalidOperationException(string message) => throw new global::System.InvalidOperationException(message);
+#if NETCOREAPP3_0_OR_GREATER
+ [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute]
+#endif
+ internal static void ThrowArgumentException(string message, string arg) => throw new global::System.ArgumentException(message, arg);
+#if NETCOREAPP3_0_OR_GREATER
+ [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute]
+#endif
+ internal static void ThrowWhenCreatedWithNull() => throw CreateCannotBeNullException();
+#if NETCOREAPP3_0_OR_GREATER
+ [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute]
+#endif
+ internal static void ThrowWhenNotInitialized() => throw CreateValidationException("Use of uninitialized Value Object.");
+#if NETCOREAPP3_0_OR_GREATER
+ [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute]
+#endif
+ internal static void ThrowWhenNotInitialized(global::System.Diagnostics.StackTrace stackTrace) => throw CreateValidationException("Use of uninitialized Value Object at: " + stackTrace ?? "");
+#if NETCOREAPP3_0_OR_GREATER
+ [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute]
+#endif
+ internal static void ThrowWhenValidationFails(Vogen.Validation validation)
+ {
+ throw CreateValidationException(validation);
+ }
+
+ internal static System.Exception CreateValidationException(string message) => new global::Vogen.ValueObjectValidationException(message);
+ internal static System.Exception CreateCannotBeNullException() => new global::Vogen.ValueObjectValidationException("Cannot create a value object with null.");
+ internal static System.Exception CreateValidationException(Vogen.Validation validation)
+ {
+ var ex = CreateValidationException(validation.ErrorMessage);
+ if (validation.Data != null)
+ {
+ foreach (var kvp in validation.Data)
+ {
+ ex.Data[kvp.Key] = kvp.Value;
+ }
+ }
+
+ return ex;
+ }
+ }
+ }
+}
+]
\ No newline at end of file
diff --git a/tests/SnapshotTests/PartialMethods/snapshots/snap-v9.0/PartialMethodsTests.Uses_method_partial_modifier_to_change_visibility.verified.txt b/tests/SnapshotTests/PartialMethods/snapshots/snap-v9.0/PartialMethodsTests.Uses_method_partial_modifier_to_change_visibility.verified.txt
new file mode 100644
index 00000000000..178760cd2fb
--- /dev/null
+++ b/tests/SnapshotTests/PartialMethods/snapshots/snap-v9.0/PartialMethodsTests.Uses_method_partial_modifier_to_change_visibility.verified.txt
@@ -0,0 +1,492 @@
+[
+// ------------------------------------------------------------------------------
+//
+// This code was generated by a source generator named Vogen (https://github.com/SteveDunn/Vogen)
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+// ------------------------------------------------------------------------------
+// Suppress warnings about [Obsolete] member usage in generated code.
+#pragma warning disable CS0618
+// Suppress warnings for 'Override methods on comparable types'.
+#pragma warning disable CA1036
+// Suppress Error MA0097 : A class that implements IComparable or IComparable should override comparison operators
+#pragma warning disable MA0097
+// Suppress warning for 'The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.'
+// The generator copies signatures from the BCL, e.g. for `TryParse`, and some of those have nullable annotations.
+#pragma warning disable CS8669, CS8632
+#pragma warning disable CS8604 // Possible null reference argument.
+
+// Suppress warnings about CS1591: Missing XML comment for publicly visible type or member 'Type_or_Member'
+#pragma warning disable CS1591
+namespace generator
+{
+ [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Vogen", "1.0.0.0")]
+ public class VogenTypesFactory : global::System.Text.Json.Serialization.JsonConverterFactory
+ {
+ public VogenTypesFactory()
+ {
+ }
+
+ private static readonly global::System.Collections.Generic.Dictionary> _lookup = new global::System.Collections.Generic.Dictionary>
+ {
+ {
+ typeof(global::Whatever.MyVo),
+ new global::System.Lazy(() => new global::Whatever.MyVo.MyVoSystemTextJsonConverter())
+ }
+ };
+ public override bool CanConvert(global::System.Type typeToConvert) => _lookup.ContainsKey(typeToConvert);
+ public override global::System.Text.Json.Serialization.JsonConverter CreateConverter(global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) => _lookup[typeToConvert].Value;
+ }
+}
+
+// ------------------------------------------------------------------------------
+//
+// This code was generated by a source generator named Vogen (https://github.com/SteveDunn/Vogen)
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+// ------------------------------------------------------------------------------
+// Suppress warnings about [Obsolete] member usage in generated code.
+#pragma warning disable CS0618
+// Suppress warnings for 'Override methods on comparable types'.
+#pragma warning disable CA1036
+// Suppress Error MA0097 : A class that implements IComparable or IComparable should override comparison operators
+#pragma warning disable MA0097
+// Suppress warning for 'The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.'
+// The generator copies signatures from the BCL, e.g. for `TryParse`, and some of those have nullable annotations.
+#pragma warning disable CS8669, CS8632
+#pragma warning disable CS8604 // Possible null reference argument.
+
+// Suppress warnings about CS1591: Missing XML comment for publicly visible type or member 'Type_or_Member'
+#pragma warning disable CS1591
+namespace Whatever
+{
+ [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Vogen", "1.0.0.0")]
+ [global::System.Text.Json.Serialization.JsonConverter(typeof(MyVoSystemTextJsonConverter))]
+ [global::System.ComponentModel.TypeConverter(typeof(MyVoTypeConverter))]
+ [global::System.Diagnostics.DebuggerTypeProxyAttribute(typeof(MyVoDebugView))]
+ [global::System.Diagnostics.DebuggerDisplayAttribute("Underlying type: System.String, Value = { _value }")]
+ public partial class MyVo : global::System.IEquatable, global::System.IEquatable, global::System.IComparable, global::System.IComparable, global::System.IParsable
+ {
+#if DEBUG
+private readonly global::System.Diagnostics.StackTrace _stackTrace = null!;
+#endif
+#if !VOGEN_NO_VALIDATION
+ private readonly global::System.Boolean _isInitialized;
+#endif
+ private readonly System.String _value;
+ ///
+ /// Gets the underlying value if set, otherwise a is thrown.
+ ///
+ public System.String Value
+ {
+ [global::System.Diagnostics.DebuggerStepThroughAttribute]
+ [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+ get
+ {
+ EnsureInitialized();
+ return _value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerStepThroughAttribute]
+ [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
+ public MyVo()
+ {
+#if DEBUG
+ _stackTrace = new global::System.Diagnostics.StackTrace();
+#endif
+#if !VOGEN_NO_VALIDATION
+ _isInitialized = false;
+#endif
+ _value = default;
+ }
+
+ [global::System.Diagnostics.DebuggerStepThroughAttribute]
+ private MyVo(System.String value)
+ {
+ _value = value;
+#if !VOGEN_NO_VALIDATION
+ _isInitialized = true;
+#endif
+ }
+
+ ///
+ /// Builds an instance from the provided underlying type.
+ ///
+ /// The underlying type.
+ /// An instance of this type.
+ [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+ private static partial MyVo From(System.String value)
+ {
+ if (value is null)
+ {
+ ThrowHelper.ThrowWhenCreatedWithNull();
+ return default !;
+ }
+
+ return new MyVo(value);
+ }
+
+ ///
+ /// Tries to build an instance from the provided underlying type.
+ /// If a normalization method is provided, it will be called.
+ /// If validation is provided, and it fails, false will be returned.
+ ///
+ /// The underlying type.
+ /// An instance of the value object.
+ /// True if the value object can be built, otherwise false.
+
+#pragma warning disable CS8767 // Nullability of reference types in type of parameter doesn't match implicitly implemented member because of nullability attributes.
+
+ internal static partial bool TryFrom(
+#if NETCOREAPP3_0_OR_GREATER
+[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
+#endif
+ System.String value,
+#if NETCOREAPP3_0_OR_GREATER
+[global::System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)]
+#endif
+ out MyVo vo)
+#pragma warning restore CS8767 // Nullability of reference types in type of parameter doesn't match implicitly implemented member because of nullability attributes.
+
+ {
+ if (value is null)
+ {
+ vo = default;
+ return false;
+ }
+
+ vo = new MyVo(value);
+ return true;
+ }
+
+ ///
+ /// Tries to build an instance from the provided underlying value.
+ /// If a normalization method is provided, it will be called.
+ /// If validation is provided, and it fails, an error will be returned.
+ ///
+ /// The primitive value.
+ /// A containing either the value object, or an error.
+ private protected static partial Vogen.ValueObjectOrError TryFrom(System.String value)
+ {
+ if (value is null)
+ {
+ return new Vogen.ValueObjectOrError(Vogen.Validation.Invalid("The value provided was null"));
+ }
+
+ return new Vogen.ValueObjectOrError(new MyVo(value));
+ }
+
+ [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+#if VOGEN_NO_VALIDATION
+#pragma warning disable CS8775
+ public bool IsInitialized() => true;
+#pragma warning restore CS8775
+#else
+ public bool IsInitialized() => _isInitialized;
+#endif
+ // only called internally when something has been deserialized into
+ // its primitive type.
+ private static MyVo __Deserialize(System.String value)
+ {
+ if (value is null)
+ {
+ ThrowHelper.ThrowWhenCreatedWithNull();
+ return default !;
+ }
+
+ return new MyVo(value);
+ }
+
+ public global::System.Boolean Equals(MyVo other)
+ {
+ if (ReferenceEquals(null, other))
+ {
+ return false;
+ }
+
+ // It's possible to create uninitialized instances via converters such as EfCore (HasDefaultValue), which call Equals.
+ // We treat anything uninitialized as not equal to anything, even other uninitialized instances of this type.
+ if (!IsInitialized() || !other.IsInitialized())
+ return false;
+ if (ReferenceEquals(this, other))
+ {
+ return true;
+ }
+
+ return GetType() == other.GetType() && global::System.Collections.Generic.EqualityComparer.Default.Equals(Value, other.Value);
+ }
+
+ public global::System.Boolean Equals(MyVo other, global::System.Collections.Generic.IEqualityComparer comparer)
+ {
+ return comparer.Equals(this, other);
+ }
+
+ public global::System.Boolean Equals(System.String primitive)
+ {
+ return Value.Equals(primitive);
+ }
+
+ public global::System.Boolean Equals(System.String primitive, global::System.StringComparer comparer)
+ {
+ return comparer.Equals(Value, primitive);
+ }
+
+ public override global::System.Boolean Equals(global::System.Object obj)
+ {
+ return Equals(obj as MyVo);
+ }
+
+ public static global::System.Boolean operator ==(MyVo left, MyVo right) => Equals(left, right);
+ public static global::System.Boolean operator !=(MyVo left, MyVo right) => !Equals(left, right);
+ public static global::System.Boolean operator ==(MyVo left, System.String right) => left.Value.Equals(right);
+ public static global::System.Boolean operator ==(System.String left, MyVo right) => right.Value.Equals(left);
+ public static global::System.Boolean operator !=(System.String left, MyVo right) => !(left == right);
+ public static global::System.Boolean operator !=(MyVo left, System.String right) => !(left == right);
+ public static explicit operator MyVo(System.String value) => From(value);
+ public static explicit operator System.String(MyVo value) => value.Value;
+ public int CompareTo(MyVo other)
+ {
+ if (other is null)
+ return 1;
+ return Value.CompareTo(other.Value);
+ }
+
+ public int CompareTo(object other)
+ {
+ if (other is null)
+ return 1;
+ if (other is MyVo x)
+ return CompareTo(x);
+ ThrowHelper.ThrowArgumentException("Cannot compare to object as it is not of type MyVo", nameof(other));
+ return 0;
+ }
+
+ ///
+ ///
+ ///
+ /// True if the value passes any validation (after running any optional normalization).
+ ///
+ public static global::System.Boolean TryParse(
+#if NETCOREAPP3_0_OR_GREATER
+[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
+#endif
+ global::System.String s, global::System.IFormatProvider provider,
+#if NETCOREAPP3_0_OR_GREATER
+[global::System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)]
+#endif
+ out MyVo result)
+ {
+ if (s is null)
+ {
+ result = default;
+ return false;
+ }
+
+ result = new MyVo(s);
+ return true;
+ }
+
+ ///
+ ///
+ ///
+ /// The value created via the method.
+ ///
+ /// Thrown when the value can be parsed, but is not valid.
+ public static MyVo Parse(global::System.String s, global::System.IFormatProvider provider)
+ {
+ return From(s);
+ }
+
+#nullable disable
+#nullable restore
+ public override global::System.Int32 GetHashCode()
+ {
+ unchecked // Overflow is fine, just wrap
+ {
+ global::System.Int32 hash = (global::System.Int32)2166136261;
+ hash = (hash * 16777619) ^ GetType().GetHashCode();
+ hash = (hash * 16777619) ^ global::System.Collections.Generic.EqualityComparer.Default.GetHashCode(Value);
+ return hash;
+ }
+ }
+
+ ///
+ public override global::System.String ToString() => IsInitialized() ? Value.ToString() ?? "" : "[UNINITIALIZED]";
+ ///
+ public global::System.String ToString(global::System.IFormatProvider provider) => IsInitialized() ? Value.ToString(provider) ?? "" : "[UNINITIALIZED]";
+ [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+ private void EnsureInitialized()
+ {
+ if (!IsInitialized())
+ {
+#if DEBUG
+ ThrowHelper.ThrowWhenNotInitialized(_stackTrace);
+#else
+ ThrowHelper.ThrowWhenNotInitialized();
+#endif
+ }
+ }
+
+#nullable disable
+ ///
+ /// Converts a MyVo to or from JSON.
+ ///
+ public partial class MyVoSystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter
+ {
+ public override MyVo Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+ return DeserializeJson(reader.GetString());
+ }
+
+ public override void Write(System.Text.Json.Utf8JsonWriter writer, MyVo value, global::System.Text.Json.JsonSerializerOptions options)
+ {
+ writer.WriteStringValue(value.Value);
+ }
+
+#if NET6_0_OR_GREATER
+ public override MyVo ReadAsPropertyName(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
+ {
+ return DeserializeJson(reader.GetString());
+ }
+
+ public override void WriteAsPropertyName(System.Text.Json.Utf8JsonWriter writer, MyVo value, global::System.Text.Json.JsonSerializerOptions options)
+ {
+ writer.WritePropertyName(value.Value);
+ }
+#endif
+#if NETCOREAPP3_0_OR_GREATER
+ [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute]
+#endif
+ private static void ThrowJsonExceptionWhenValidationFails(Vogen.Validation validation)
+ {
+ var e = ThrowHelper.CreateValidationException(validation);
+ throw new global::System.Text.Json.JsonException(null, e);
+ }
+
+ private static void ThrowJsonExceptionWhenNull(System.String value)
+ {
+ if (value == null)
+ {
+ var e = ThrowHelper.CreateCannotBeNullException();
+ throw new global::System.Text.Json.JsonException(null, e);
+ }
+ }
+
+ private static MyVo DeserializeJson(System.String value)
+ {
+ ThrowJsonExceptionWhenNull(value);
+ return new MyVo(value);
+ }
+ }
+
+#nullable restore
+#nullable disable
+ class MyVoTypeConverter : global::System.ComponentModel.TypeConverter
+ {
+ public override global::System.Boolean CanConvertFrom(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Type sourceType)
+ {
+ return sourceType == typeof(global::System.String) || base.CanConvertFrom(context, sourceType);
+ }
+
+ public override global::System.Object ConvertFrom(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Globalization.CultureInfo culture, global::System.Object value)
+ {
+ var stringValue = value as global::System.String;
+ if (stringValue != null)
+ {
+ return MyVo.__Deserialize(stringValue);
+ }
+
+ return base.ConvertFrom(context, culture, value);
+ }
+
+ public override bool CanConvertTo(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Type sourceType)
+ {
+ return sourceType == typeof(global::System.String) || base.CanConvertTo(context, sourceType);
+ }
+
+ public override object ConvertTo(global::System.ComponentModel.ITypeDescriptorContext context, global::System.Globalization.CultureInfo culture, global::System.Object value, global::System.Type destinationType)
+ {
+ if (value is MyVo idValue)
+ {
+ if (destinationType == typeof(global::System.String))
+ {
+ return idValue.Value;
+ }
+ }
+
+ return base.ConvertTo(context, culture, value, destinationType);
+ }
+ }
+
+#nullable restore
+ internal sealed class MyVoDebugView
+ {
+ private readonly MyVo _t;
+ MyVoDebugView(MyVo t)
+ {
+ _t = t;
+ }
+
+ public global::System.String UnderlyingType => "System.String";
+ public System.String Value => _t.Value;
+ public global::System.String Conversions => @"[global::System.Text.Json.Serialization.JsonConverter(typeof(MyVoSystemTextJsonConverter))]
+[global::System.ComponentModel.TypeConverter(typeof(MyVoTypeConverter))]
+";
+ }
+
+ static class ThrowHelper
+ {
+#if NETCOREAPP3_0_OR_GREATER
+ [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute]
+#endif
+ internal static void ThrowInvalidOperationException(string message) => throw new global::System.InvalidOperationException(message);
+#if NETCOREAPP3_0_OR_GREATER
+ [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute]
+#endif
+ internal static void ThrowArgumentException(string message, string arg) => throw new global::System.ArgumentException(message, arg);
+#if NETCOREAPP3_0_OR_GREATER
+ [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute]
+#endif
+ internal static void ThrowWhenCreatedWithNull() => throw CreateCannotBeNullException();
+#if NETCOREAPP3_0_OR_GREATER
+ [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute]
+#endif
+ internal static void ThrowWhenNotInitialized() => throw CreateValidationException("Use of uninitialized Value Object.");
+#if NETCOREAPP3_0_OR_GREATER
+ [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute]
+#endif
+ internal static void ThrowWhenNotInitialized(global::System.Diagnostics.StackTrace stackTrace) => throw CreateValidationException("Use of uninitialized Value Object at: " + stackTrace ?? "");
+#if NETCOREAPP3_0_OR_GREATER
+ [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute]
+#endif
+ internal static void ThrowWhenValidationFails(Vogen.Validation validation)
+ {
+ throw CreateValidationException(validation);
+ }
+
+ internal static System.Exception CreateValidationException(string message) => new global::Vogen.ValueObjectValidationException(message);
+ internal static System.Exception CreateCannotBeNullException() => new global::Vogen.ValueObjectValidationException("Cannot create a value object with null.");
+ internal static System.Exception CreateValidationException(Vogen.Validation validation)
+ {
+ var ex = CreateValidationException(validation.ErrorMessage);
+ if (validation.Data != null)
+ {
+ foreach (var kvp in validation.Data)
+ {
+ ex.Data[kvp.Key] = kvp.Value;
+ }
+ }
+
+ return ex;
+ }
+ }
+ }
+}
+]
\ No newline at end of file