Skip to content

Commit

Permalink
Only generate additional properties at base class level (RicoSuter#1512)
Browse files Browse the repository at this point in the history
  • Loading branch information
sdecoodt authored May 8, 2022
1 parent fca4d1f commit c66ffc8
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using NJsonSchema.CodeGeneration.CSharp;
Expand Down Expand Up @@ -141,7 +141,84 @@ public async Task When_using_SystemTextJson_additionalProperties_schema_is_set_f
// There are two matches, the Person class and the Pet class
Assert.Equal(2, matches.Count);
}

[Fact]
public async Task When_using_SystemTextJson_additionalProperties_schema_is_set_for_object_then_special_property_is_rendered_only_for_lowest_base_class()
{
var json =
@"{
""properties"": {
""Name"": {
""type"": ""string""
}
},
""definitions"": {
""Cat"": {
""allOf"": [
{
""$ref"": ""#/definitions/Pet""
},
{
""type"": ""object"",
""additionalProperties"": {
""nullable"": true
},
""properties"": {
""whiskers"": {
""type"": ""string""
}
}
}
]
},
""Pet"": {
""allOf"": [
{
""$ref"": ""#/definitions/Animal""
},
{
""type"": ""object"",
""additionalProperties"": {
""nullable"": true
},
""properties"": {
""id"": {
""type"": ""integer"",
""format"": ""int64""
}
}
}
]
},
""Animal"": {
""type"": ""object"",
""properties"": {
""category"": {
""type"": ""string"",
""nullable"": true
}
}
}
}
}";

var schema = await JsonSchema.FromJsonAsync(json);

//// Act
var generator = new CSharpGenerator(schema, new CSharpGeneratorSettings()
{
JsonLibrary = CSharpJsonLibrary.SystemTextJson
});

var code = generator.GenerateFile("SommeDummyClass");

//// Assert
var matches = Regex.Matches(code, @"(\[System\.Text\.Json\.Serialization\.JsonExtensionData\])");

// There are two matches, the SommeDummyClass class and the Animal class
Assert.Equal(2, matches.Count);
}

public class Page
{
}
Expand Down
14 changes: 10 additions & 4 deletions src/NJsonSchema.CodeGeneration.CSharp/Models/ClassTemplateModel.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// <copyright file="ClassTemplateModel.cs" company="NJsonSchema">
// Copyright (c) Rico Suter. All rights reserved.
// </copyright>
Expand Down Expand Up @@ -62,15 +62,21 @@ public ClassTemplateModel(string typeName, CSharpGeneratorSettings settings,
/// <summary>Gets a value indicating whether the C#8 nullable reference types are enabled for this file.</summary>
public bool GenerateNullableReferenceTypes => _settings.GenerateNullableReferenceTypes;

/// <summary>Gets a value indicating whether an additional properties type is available and needed.</summary>
/// <summary>Gets a value indicating whether an additional properties type is available.</summary>
public bool HasAdditionalPropertiesType =>
HasAdditionalPropertiesTypeInBaseClass || // if the base class has them, inheritance dictates that this class will have them to
!_schema.IsDictionary &&
!_schema.ActualTypeSchema.IsDictionary &&
!_schema.IsArray &&
!_schema.ActualTypeSchema.IsArray &&
(_schema.ActualTypeSchema.AllowAdditionalProperties ||
_schema.ActualTypeSchema.AdditionalPropertiesSchema != null)
&& BaseClass?.HasAdditionalPropertiesType != true; // if base class already has extension data array, we need to avoid it in the subclass
_schema.ActualTypeSchema.AdditionalPropertiesSchema != null);

/// <summary>Gets a value indicating whether an additional properties type is available in the base class.</summary>
public bool HasAdditionalPropertiesTypeInBaseClass => BaseClass?.HasAdditionalPropertiesType ?? false;

/// <summary> Gets a value indicating if the "Additional properties" property should be generated. </summary>
public bool GenerateAdditionalPropertiesProperty => HasAdditionalPropertiesType && !HasAdditionalPropertiesTypeInBaseClass;

/// <summary>Gets the type of the additional properties.</summary>
public string AdditionalPropertiesType => HasAdditionalPropertiesType ? "object" : null; // TODO: Find a way to use typed dictionaries
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@
{%- endif %}
{%- endfor -%}

{%- if HasAdditionalPropertiesType -%}
{%- if GenerateAdditionalPropertiesProperty -%}

private System.Collections.Generic.IDictionary<string, {{ AdditionalPropertiesType }}> _additionalProperties = new System.Collections.Generic.Dictionary<string, {{ AdditionalPropertiesType }}>();

Expand Down

0 comments on commit c66ffc8

Please sign in to comment.