Skip to content

Commit

Permalink
Thow JsonExceptions from throw helper to enable inlining
Browse files Browse the repository at this point in the history
  • Loading branch information
Peter-B- committed Jan 7, 2025
1 parent e5ca2ff commit 9a58511
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,48 @@ namespace Vogen.Generators.Conversions;

internal class GenerateSystemTextJsonConversions : IGenerateConversion
{
private static readonly string DeserializeJsonMethod =
"""
private static VOTYPE DeserializeJson(VOUNDERLYINGTYPE value)
{
try
{
return VOTYPE.__Deserialize(value);
}
catch (System.Exception e)
{
throw new global::System.Text.Json.JsonException(null, e);
}
}
""";
private static string GenerateDeserializeJsonMethod(VoWorkItem item) => $$"""
#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);
}
{{GenerateThrowExceptionHelperIfNeeded(item)}}
public static VOTYPE DeserializeJson(VOUNDERLYINGTYPE value)
{
{{GenerateNullCheckAndThrowJsonExceptionIfNeeded(item)}}
{{Util.GenerateCallToNormalizeMethodIfNeeded(item)}}
{{Util.GenerateCallToValidationAndThrowIfRequired(item, "ThrowJsonExceptionWhenValidationFails")}}
return new VOTYPE(value);
}
"""
.Replace("\n", "\n ");

private static string GenerateThrowExceptionHelperIfNeeded(VoWorkItem voWorkItem) =>
voWorkItem.IsTheUnderlyingAValueType ? string.Empty
: """
private static void ThrowJsonExceptionWhenNull(VOUNDERLYINGTYPE value)
{
if (value == null)
{
var e = ThrowHelper.CreateCannotBeNullException();
throw new global::System.Text.Json.JsonException(null, e);
}
}
""";

private static string GenerateNullCheckAndThrowJsonExceptionIfNeeded(VoWorkItem voWorkItem) =>
voWorkItem.IsTheUnderlyingAValueType ? string.Empty
: $$"""
ThrowJsonExceptionWhenNull(value);
""";

public string GenerateAnyAttributes(TypeDeclarationSyntax tds, VoWorkItem item)
{
Expand Down Expand Up @@ -47,9 +75,9 @@ public string GenerateAnyBody(TypeDeclarationSyntax tds, VoWorkItem item)
{
allowNullReferences = false;
}

}

code = allowNullReferences ? CodeSections.CutSection(code, "__HANDLE_NULL__") : CodeSections.KeepSection(code, "__HANDLE_NULL__");

if (code.Contains("__NORMAL__"))
Expand All @@ -63,7 +91,7 @@ public string GenerateAnyBody(TypeDeclarationSyntax tds, VoWorkItem item)
code = CodeSections.KeepSection(code, keepCut.keep);
}

code = code.Replace("DESERIALIZEJSONMETHOD", DeserializeJsonMethod.Replace("\n", "\n "));
code = code.Replace("DESERIALIZEJSONMETHOD", GenerateDeserializeJsonMethod(item));

code = code.Replace("VOTYPE", item.VoTypeName);
code = code.Replace("VOUNDERLYINGTYPE", item.UnderlyingTypeFullName);
Expand Down
115 changes: 63 additions & 52 deletions src/Vogen/Util.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,15 @@ public static void TryWriteUsingUniqueFilename(string filename, SourceProduction
}


public static string GenerateCallToValidationAndThrowIfRequired(VoWorkItem workItem)
public static string GenerateCallToValidationAndThrowIfRequired(VoWorkItem workItem, string throwingMethod = "ThrowHelper.ThrowWhenValidationFails")
{
if (workItem.ValidateMethod is not null)
{
return $$"""
var validation = {{workItem.TypeToAugment.Identifier}}.{{workItem.ValidateMethod.Identifier.Value}}(value);
if (validation != Vogen.Validation.Ok)
{
ThrowHelper.ThrowWhenValidationFails(validation);
{{throwingMethod}}(validation);
}
""";
Expand Down Expand Up @@ -378,56 +378,67 @@ public static string GenerateEnsureInitializedMethod(VoWorkItem item, bool readO

public static string GenerateThrowHelper(VoWorkItem item)
{
return $$"""
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 new {{item.ValidationExceptionFullName}}("Cannot create a value object with null.");
#if NETCOREAPP3_0_OR_GREATER
[global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute]
#endif
internal static void ThrowWhenNotInitialized() =>
throw new {{item.ValidationExceptionFullName}}("Use of uninitialized Value Object.");
#if NETCOREAPP3_0_OR_GREATER
[global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute]
#endif
internal static void ThrowWhenNotInitialized(global::System.Diagnostics.StackTrace{{item.Nullable.QuestionMarkForOtherReferences}} stackTrace) =>
throw new {{item.ValidationExceptionFullName}}({{GetMessageToReport(item)}});
#if NETCOREAPP3_0_OR_GREATER
[global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute]
#endif
internal static void ThrowWhenValidationFails(Vogen.Validation validation)
{
var ex = new {{item.ValidationExceptionFullName}}(validation.ErrorMessage);
if (validation.Data is not null)
{
foreach (var kvp in validation.Data)
{
ex.Data[kvp.Key] = kvp.Value;
}
}
throw ex;
}
}
""";
return $$$"""
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{{{item.Nullable.QuestionMarkForOtherReferences}}} stackTrace) =>
throw CreateValidationException({{{GetMessageToReport(item)}}});
#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 {{{item.ValidationExceptionFullName}}}(message);
internal static System.Exception CreateCannotBeNullException() =>
new {{{item.ValidationExceptionFullName}}}("Cannot create a value object with null.");
internal static System.Exception CreateValidationException(Vogen.Validation validation)
{
var ex = CreateValidationException(validation.ErrorMessage);
if (validation.Data is not null)
{
foreach (var kvp in validation.Data)
{
ex.Data[kvp.Key] = kvp.Value;
}
}
return ex;
}
}
""";

static string GetMessageToReport(VoWorkItem item) =>
item.Config.DisableStackTraceRecordingInDebug
Expand Down

0 comments on commit 9a58511

Please sign in to comment.