Skip to content

Commit 5bdd949

Browse files
committed
fix: Fixed issues with AllOf polymorphism.
1 parent ff2004d commit 5bdd949

File tree

4 files changed

+64
-36
lines changed

4 files changed

+64
-36
lines changed

src/libs/AutoSDK/Models/TypeData.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ namespace AutoSDK.Models;
66
public readonly record struct TypeData(
77
string CSharpTypeRaw,
88
bool CSharpTypeNullability,
9+
bool IsBaseClass,
10+
bool IsDerivedClass,
911
bool IsArray,
1012
bool IsNullable,
1113
bool IsEnum,
@@ -30,6 +32,8 @@ public readonly record struct TypeData(
3032
public static TypeData Default => new(
3133
CSharpTypeRaw: string.Empty,
3234
CSharpTypeNullability: false,
35+
IsBaseClass: false,
36+
IsDerivedClass: false,
3337
IsArray: false,
3438
IsNullable: false,
3539
IsEnum: false,
@@ -161,6 +165,8 @@ Default with
161165
return new TypeData(
162166
CSharpTypeRaw: type,
163167
CSharpTypeNullability: GetCSharpNullability(context),
168+
IsBaseClass: context.IsBaseClass,
169+
IsDerivedClass: context.IsDerivedClass,
164170
IsValueType: ContextIsValueType(context),
165171
IsNullable: context.Schema.Nullable,
166172
IsArray: context.Schema.IsArray(),

src/libs/AutoSDK/Serialization/Json/SystemTextJsonSerializer.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,12 @@ public string GenerateSerializeCall(TypeData type, string jsonSerializerContext)
107107

108108
public string GenerateDeserializeCall(string variableName, TypeData type, string jsonSerializerContext)
109109
{
110+
var typeToDeserializeIfRequired = type.IsDerivedClass || type.IsBaseClass ? $"<{type.CSharpTypeWithoutNullability}>" : "";
110111
if (type.CSharpType.StartsWith($"global::{type.Settings.Namespace}", StringComparison.Ordinal))
111112
{
112113
return string.IsNullOrWhiteSpace(jsonSerializerContext)
113-
? $"{type.CSharpTypeWithoutNullability}.FromJson({variableName}, JsonSerializerOptions)"
114-
: $"{type.CSharpTypeWithoutNullability}.FromJson({variableName}, JsonSerializerContext)";
114+
? $"{type.CSharpTypeWithoutNullability}.FromJson{typeToDeserializeIfRequired}({variableName}, JsonSerializerOptions)"
115+
: $"{type.CSharpTypeWithoutNullability}.FromJson{typeToDeserializeIfRequired}({variableName}, JsonSerializerContext)";
115116
}
116117

117118
return string.IsNullOrWhiteSpace(jsonSerializerContext)
@@ -121,11 +122,12 @@ public string GenerateDeserializeCall(string variableName, TypeData type, string
121122

122123
public string GenerateDeserializeFromStreamCall(string variableName, TypeData type, string jsonSerializerContext)
123124
{
125+
var typeToDeserializeIfRequired = type.IsDerivedClass || type.IsBaseClass ? $"<{type.CSharpTypeWithoutNullability}>" : "";
124126
if (type.CSharpType.StartsWith($"global::{type.Settings.Namespace}", StringComparison.Ordinal))
125127
{
126128
return string.IsNullOrWhiteSpace(jsonSerializerContext)
127-
? $"await {type.CSharpTypeWithoutNullability}.FromJsonStreamAsync({variableName}, JsonSerializerOptions).ConfigureAwait(false)"
128-
: $"await {type.CSharpTypeWithoutNullability}.FromJsonStreamAsync({variableName}, JsonSerializerContext).ConfigureAwait(false)";
129+
? $"await {type.CSharpTypeWithoutNullability}.FromJsonStreamAsync{typeToDeserializeIfRequired}({variableName}, JsonSerializerOptions).ConfigureAwait(false)"
130+
: $"await {type.CSharpTypeWithoutNullability}.FromJsonStreamAsync{typeToDeserializeIfRequired}({variableName}, JsonSerializerContext).ConfigureAwait(false)";
129131
}
130132

131133
return string.IsNullOrWhiteSpace(jsonSerializerContext)

src/libs/AutoSDK/Sources/Sources.Models.Json.cs

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ public static string GenerateModelFromToJsonMethods(
5757
var modifiers = isValueType
5858
? "readonly partial struct"
5959
: $"{(isBaseClass ? "" : "sealed ")}partial class";
60-
var isDerivedClass = !string.IsNullOrWhiteSpace(baseClassName);
6160

6261
return settings.JsonSerializerType == JsonSerializerType.SystemTextJson
6362
? @$"#nullable enable
@@ -72,7 +71,7 @@ public string ToJson(
7271
{{
7372
return global::System.Text.Json.JsonSerializer.Serialize(
7473
this,
75-
{(isDerivedClass ? $"typeof({baseClassName})" : "this.GetType()")},
74+
{(isBaseClass ? $"typeof({className})" : "this.GetType()")},
7675
jsonSerializerContext);
7776
}}
7877
@@ -86,67 +85,83 @@ public string ToJson(
8685
{{
8786
return global::System.Text.Json.JsonSerializer.Serialize(
8887
this,
89-
{(isDerivedClass ? $"typeof({baseClassName})," : string.Empty)}
88+
{(isBaseClass ? $"typeof({className})," : string.Empty)}
9089
jsonSerializerOptions);
9190
}}
9291
9392
{"Deserializes a JSON string using the provided JsonSerializerContext.".ToXmlDocumentationSummary(level: 8)}
94-
public static {typeName}? FromJson{(isDerivedClass ? "<T>" : string.Empty)}(
93+
public static {(isBaseClass ? "T" : typeName)}? FromJson{(isBaseClass ? "<T>" : string.Empty)}(
9594
string json,
9695
global::System.Text.Json.Serialization.JsonSerializerContext jsonSerializerContext)
97-
{(isDerivedClass ? $"where T : {baseClassName}" : string.Empty)}
96+
{(isBaseClass ? $"where T : {className}" : string.Empty)}
9897
{{
9998
return global::System.Text.Json.JsonSerializer.Deserialize(
10099
json,
101-
typeof({(isDerivedClass ? baseClassName : typeName)}),
102-
jsonSerializerContext) as {(isDerivedClass ? "T" : typeName)}{(isValueType ? "?" : "")};
100+
typeof({(isBaseClass ? className : typeName)}),
101+
jsonSerializerContext) as {(isBaseClass ? "T" : typeName)}{(isValueType ? "?" : "")};
103102
}}
104103
105104
{"Deserializes a JSON string using the provided JsonSerializerOptions.".ToXmlDocumentationSummary(level: 8)}
106105
#if NET8_0_OR_GREATER
107106
[global::System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode(""JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved."")]
108107
[global::System.Diagnostics.CodeAnalysis.RequiresDynamicCode(""JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications."")]
109108
#endif
110-
public static {typeName}? FromJson{(isDerivedClass ? "<T>" : string.Empty)}(
109+
public static {(isBaseClass ? "T" : typeName)}? FromJson{(isBaseClass ? "<T>" : string.Empty)}(
111110
string json,
112111
global::System.Text.Json.JsonSerializerOptions? jsonSerializerOptions = null)
113-
{(isDerivedClass ? $"where T : {baseClassName}" : string.Empty)}
112+
{(isBaseClass ? $"where T : {className}" : string.Empty)}
114113
{{
115-
return global::System.Text.Json.JsonSerializer.Deserialize<{(isDerivedClass ? baseClassName : typeName)}>(
114+
return global::System.Text.Json.JsonSerializer.Deserialize<{(isBaseClass ? className : typeName)}>(
116115
json,
117-
jsonSerializerOptions){(isDerivedClass ? " as T" : string.Empty)};
116+
jsonSerializerOptions){(isBaseClass ? " as T" : string.Empty)};
118117
}}
119118
120119
/// <summary>
121120
/// Deserializes a JSON stream using the provided JsonSerializerContext.
122121
/// </summary>
123-
public static async global::System.Threading.Tasks.ValueTask<{typeName}?> FromJsonStreamAsync{(isDerivedClass ? "<T>" : string.Empty)}(
122+
public static async global::System.Threading.Tasks.ValueTask<{(isBaseClass ? "T?" : $"{typeName}?")}> FromJsonStreamAsync{(isBaseClass ? "<T>" : string.Empty)}(
124123
global::System.IO.Stream jsonStream,
125124
global::System.Text.Json.Serialization.JsonSerializerContext jsonSerializerContext)
126-
{(isDerivedClass ? $"where T : {baseClassName}" : string.Empty)}
125+
{(isBaseClass ? $"where T : {className}" : string.Empty)}
127126
{{
128127
return (await global::System.Text.Json.JsonSerializer.DeserializeAsync(
129128
jsonStream,
130-
typeof({(isDerivedClass ? baseClassName : typeName)}),
131-
jsonSerializerContext).ConfigureAwait(false)) as {(isDerivedClass ? "T" : typeName)}{(isValueType ? "?" : "")};
129+
typeof({(isBaseClass ? className : typeName)}),
130+
jsonSerializerContext).ConfigureAwait(false)) as {(isBaseClass ? "T" : typeName)}{(isValueType ? "?" : "")};
132131
}}
133132
133+
{(isBaseClass ? $@"
134134
/// <summary>
135135
/// Deserializes a JSON stream using the provided JsonSerializerOptions.
136136
/// </summary>
137137
#if NET8_0_OR_GREATER
138138
[global::System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode(""JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved."")]
139139
[global::System.Diagnostics.CodeAnalysis.RequiresDynamicCode(""JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications."")]
140140
#endif
141-
public static global::System.Threading.Tasks.ValueTask<{typeName}?> FromJsonStreamAsync{(isDerivedClass ? "<T>" : string.Empty)}(
141+
public static async global::System.Threading.Tasks.ValueTask<T?> FromJsonStreamAsync<T>(
142+
global::System.IO.Stream jsonStream,
143+
global::System.Text.Json.JsonSerializerOptions? jsonSerializerOptions = null)
144+
where T : {className}
145+
{{
146+
return (await global::System.Text.Json.JsonSerializer.DeserializeAsync<{className}?>(
147+
jsonStream,
148+
jsonSerializerOptions).ConfigureAwait(false)) as T{(isValueType ? "?" : "")};
149+
}}" : $@"
150+
/// <summary>
151+
/// Deserializes a JSON stream using the provided JsonSerializerOptions.
152+
/// </summary>
153+
#if NET8_0_OR_GREATER
154+
[global::System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode(""JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved."")]
155+
[global::System.Diagnostics.CodeAnalysis.RequiresDynamicCode(""JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications."")]
156+
#endif
157+
public static global::System.Threading.Tasks.ValueTask<{typeName}?> FromJsonStreamAsync(
142158
global::System.IO.Stream jsonStream,
143159
global::System.Text.Json.JsonSerializerOptions? jsonSerializerOptions = null)
144-
{(isDerivedClass ? $"where T : {baseClassName}" : string.Empty)}
145160
{{
146161
return global::System.Text.Json.JsonSerializer.DeserializeAsync<{typeName}?>(
147162
jsonStream,
148-
jsonSerializerOptions){(isDerivedClass ? " as T" : string.Empty)};
149-
}}
163+
jsonSerializerOptions);
164+
}}")}
150165
}}
151166
}}
152167
".RemoveBlankLinesWhereOnlyWhitespaces()

src/tests/AutoSDK.SnapshotTests/Snapshots/cohere/SystemTextJson/_#G.Models.ChatStreamEvent.Json.g.verified.cs

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public string ToJson(
1313
{
1414
return global::System.Text.Json.JsonSerializer.Serialize(
1515
this,
16-
this.GetType(),
16+
typeof(ChatStreamEvent),
1717
jsonSerializerContext);
1818
}
1919

@@ -29,20 +29,22 @@ public string ToJson(
2929
{
3030
return global::System.Text.Json.JsonSerializer.Serialize(
3131
this,
32+
typeof(ChatStreamEvent),
3233
jsonSerializerOptions);
3334
}
3435

3536
/// <summary>
3637
/// Deserializes a JSON string using the provided JsonSerializerContext.
3738
/// </summary>
38-
public static global::G.ChatStreamEvent? FromJson(
39+
public static T? FromJson<T>(
3940
string json,
4041
global::System.Text.Json.Serialization.JsonSerializerContext jsonSerializerContext)
42+
where T : ChatStreamEvent
4143
{
4244
return global::System.Text.Json.JsonSerializer.Deserialize(
4345
json,
44-
typeof(global::G.ChatStreamEvent),
45-
jsonSerializerContext) as global::G.ChatStreamEvent;
46+
typeof(ChatStreamEvent),
47+
jsonSerializerContext) as T;
4648
}
4749

4850
/// <summary>
@@ -52,26 +54,28 @@ public string ToJson(
5254
[global::System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")]
5355
[global::System.Diagnostics.CodeAnalysis.RequiresDynamicCode("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")]
5456
#endif
55-
public static global::G.ChatStreamEvent? FromJson(
57+
public static T? FromJson<T>(
5658
string json,
5759
global::System.Text.Json.JsonSerializerOptions? jsonSerializerOptions = null)
60+
where T : ChatStreamEvent
5861
{
59-
return global::System.Text.Json.JsonSerializer.Deserialize<global::G.ChatStreamEvent>(
62+
return global::System.Text.Json.JsonSerializer.Deserialize<ChatStreamEvent>(
6063
json,
61-
jsonSerializerOptions);
64+
jsonSerializerOptions) as T;
6265
}
6366

6467
/// <summary>
6568
/// Deserializes a JSON stream using the provided JsonSerializerContext.
6669
/// </summary>
67-
public static async global::System.Threading.Tasks.ValueTask<global::G.ChatStreamEvent?> FromJsonStreamAsync(
70+
public static async global::System.Threading.Tasks.ValueTask<T?> FromJsonStreamAsync<T>(
6871
global::System.IO.Stream jsonStream,
6972
global::System.Text.Json.Serialization.JsonSerializerContext jsonSerializerContext)
73+
where T : ChatStreamEvent
7074
{
7175
return (await global::System.Text.Json.JsonSerializer.DeserializeAsync(
7276
jsonStream,
73-
typeof(global::G.ChatStreamEvent),
74-
jsonSerializerContext).ConfigureAwait(false)) as global::G.ChatStreamEvent;
77+
typeof(ChatStreamEvent),
78+
jsonSerializerContext).ConfigureAwait(false)) as T;
7579
}
7680

7781
/// <summary>
@@ -81,13 +85,14 @@ public string ToJson(
8185
[global::System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")]
8286
[global::System.Diagnostics.CodeAnalysis.RequiresDynamicCode("JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications.")]
8387
#endif
84-
public static global::System.Threading.Tasks.ValueTask<global::G.ChatStreamEvent?> FromJsonStreamAsync(
88+
public static async global::System.Threading.Tasks.ValueTask<T?> FromJsonStreamAsync<T>(
8589
global::System.IO.Stream jsonStream,
8690
global::System.Text.Json.JsonSerializerOptions? jsonSerializerOptions = null)
91+
where T : ChatStreamEvent
8792
{
88-
return global::System.Text.Json.JsonSerializer.DeserializeAsync<global::G.ChatStreamEvent?>(
93+
return (await global::System.Text.Json.JsonSerializer.DeserializeAsync<ChatStreamEvent?>(
8994
jsonStream,
90-
jsonSerializerOptions);
95+
jsonSerializerOptions).ConfigureAwait(false)) as T;
9196
}
9297
}
9398
}

0 commit comments

Comments
 (0)