From eaeff0144edad44775c31a4d29b03f15fe4813b6 Mon Sep 17 00:00:00 2001 From: Rico Suter Date: Fri, 21 Sep 2018 21:13:06 +0200 Subject: [PATCH] Revert "Use allOf for all schemas in inheritance (#733)" This reverts commit 74aa14f3c2331eb29feca5488a61b27ed5c80e21. --- .../GeneralGeneratorTests.cs | 4 +- .../AbstractGenerationTests.cs | 9 +-- .../TypeScriptGeneratorTests.cs | 4 +- .../Models/ClassTemplateModelBase.cs | 4 +- .../Conversion/ArrayTypeToSchemaTests.cs | 2 +- .../Generation/ExceptionTypeTests.cs | 4 +- .../Generation/InheritanceTests.cs | 44 ++----------- .../Generation/JsonSchemaGenerator.cs | 66 +++++++------------ .../XmlDocumentationExtensions.cs | 6 +- src/NJsonSchema/JsonSchema4.Reference.cs | 15 +---- 10 files changed, 38 insertions(+), 120 deletions(-) diff --git a/src/NJsonSchema.CodeGeneration.CSharp.Tests/GeneralGeneratorTests.cs b/src/NJsonSchema.CodeGeneration.CSharp.Tests/GeneralGeneratorTests.cs index 5b6fa72ec..44742c959 100644 --- a/src/NJsonSchema.CodeGeneration.CSharp.Tests/GeneralGeneratorTests.cs +++ b/src/NJsonSchema.CodeGeneration.CSharp.Tests/GeneralGeneratorTests.cs @@ -278,7 +278,7 @@ public async Task When_class_has_description_then_csharp_has_xml_comment() { //// Arrange var schema = await JsonSchema4.FromTypeAsync(); - schema.ActualSchema.Description = "ClassDesc."; + schema.Description = "ClassDesc."; var generator = new CSharpGenerator(schema); //// Act @@ -295,7 +295,7 @@ public async Task When_property_has_description_then_csharp_has_xml_comment() { //// Arrange var schema = await JsonSchema4.FromTypeAsync(); - schema.ActualProperties["Class"].Description = "PropertyDesc."; + schema.Properties["Class"].Description = "PropertyDesc."; var generator = new CSharpGenerator(schema, new CSharpGeneratorSettings { ClassStyle = CSharpClassStyle.Poco }); //// Act diff --git a/src/NJsonSchema.CodeGeneration.TypeScript.Tests/AbstractGenerationTests.cs b/src/NJsonSchema.CodeGeneration.TypeScript.Tests/AbstractGenerationTests.cs index 74c8b5a8c..bda9c81fa 100644 --- a/src/NJsonSchema.CodeGeneration.TypeScript.Tests/AbstractGenerationTests.cs +++ b/src/NJsonSchema.CodeGeneration.TypeScript.Tests/AbstractGenerationTests.cs @@ -19,7 +19,6 @@ public async Task When_class_is_abstract_then_is_abstract_TypeScript_keyword_is_ { /// Arrange var schema = await JsonSchema4.FromTypeAsync(); - var json = schema.ToJson(); /// Act var generator = new TypeScriptGenerator(schema, new TypeScriptGeneratorSettings { TypeScriptVersion = 2.0m }); @@ -27,10 +26,6 @@ public async Task When_class_is_abstract_then_is_abstract_TypeScript_keyword_is_ /// Assert Assert.Contains("export abstract class AbstractClass", code); - - Assert.Contains("base: string", code); - Assert.Contains("super: string", code); - Assert.Contains("foo: string", code); } public class ContainerClass @@ -58,12 +53,12 @@ public async Task When_property_is_required_and_abstract_then_it_is_not_instanti [JsonConverter(typeof(JsonInheritanceConverter))] public class BaseClass { - public string Base { get; set; } + } public class SuperClass : AbstractClass { - public string Super { get; set; } + } [Fact] diff --git a/src/NJsonSchema.CodeGeneration.TypeScript.Tests/TypeScriptGeneratorTests.cs b/src/NJsonSchema.CodeGeneration.TypeScript.Tests/TypeScriptGeneratorTests.cs index 5ca3fddbc..844253b86 100644 --- a/src/NJsonSchema.CodeGeneration.TypeScript.Tests/TypeScriptGeneratorTests.cs +++ b/src/NJsonSchema.CodeGeneration.TypeScript.Tests/TypeScriptGeneratorTests.cs @@ -154,9 +154,7 @@ public async Task When_property_has_description_then_csharp_has_xml_comment() { //// Arrange var schema = await JsonSchema4.FromTypeAsync(); - schema.ActualProperties["Class"].Description = "PropertyDesc."; - var json = schema.ToJson(); - + schema.Properties["Class"].Description = "PropertyDesc."; var generator = new TypeScriptGenerator(schema); //// Act diff --git a/src/NJsonSchema.CodeGeneration/Models/ClassTemplateModelBase.cs b/src/NJsonSchema.CodeGeneration/Models/ClassTemplateModelBase.cs index 416153c96..1e3eee897 100644 --- a/src/NJsonSchema.CodeGeneration/Models/ClassTemplateModelBase.cs +++ b/src/NJsonSchema.CodeGeneration/Models/ClassTemplateModelBase.cs @@ -33,7 +33,7 @@ protected ClassTemplateModelBase(TypeResolverBase resolver, JsonSchema4 schema, public abstract string ClassName { get; } /// Gets or sets a value indicating whether the type is abstract. - public bool IsAbstract => _schema.ActualTypeSchema.IsAbstract; + public bool IsAbstract => _schema.IsAbstract; /// Gets the property extension data. public IDictionary ExtensionData => _schema.ExtensionData; @@ -49,7 +49,7 @@ public class DerivedClassModel { internal DerivedClassModel(string typeName, JsonSchema4 schema, OpenApiDiscriminator discriminator, TypeResolverBase resolver) { - var mapping = discriminator.Mapping.SingleOrDefault(m => m.Value.ActualTypeSchema == schema.ActualTypeSchema); + var mapping = discriminator.Mapping.SingleOrDefault(m => m.Value.ActualSchema == schema.ActualSchema); ClassName = resolver.GetOrGenerateTypeName(schema, typeName); IsAbstract = schema.ActualTypeSchema.IsAbstract; diff --git a/src/NJsonSchema.Tests/Conversion/ArrayTypeToSchemaTests.cs b/src/NJsonSchema.Tests/Conversion/ArrayTypeToSchemaTests.cs index 4b11814a0..800a5570a 100644 --- a/src/NJsonSchema.Tests/Conversion/ArrayTypeToSchemaTests.cs +++ b/src/NJsonSchema.Tests/Conversion/ArrayTypeToSchemaTests.cs @@ -32,7 +32,7 @@ public async Task When_converting_type_inheriting_from_dictionary_then_it_should var data = schema.ToJson(); //// Assert - Assert.Equal(JsonObjectType.Object, schema.ActualTypeSchema.Type); + Assert.Equal(JsonObjectType.Object, schema.Type); Assert.DoesNotContain("Foo", json); Assert.DoesNotContain("foo", json); } diff --git a/src/NJsonSchema.Tests/Generation/ExceptionTypeTests.cs b/src/NJsonSchema.Tests/Generation/ExceptionTypeTests.cs index 4e3afc741..c2c7d65cc 100644 --- a/src/NJsonSchema.Tests/Generation/ExceptionTypeTests.cs +++ b/src/NJsonSchema.Tests/Generation/ExceptionTypeTests.cs @@ -24,8 +24,8 @@ public async Task When_exception_schema_is_generated_then_special_properties_are var exceptionSchema = schema.InheritedSchema.ActualSchema; //// Assert - Assert.True(schema.ActualProperties.ContainsKey("foo")); - Assert.True(exceptionSchema.ActualProperties.ContainsKey("InnerException")); + Assert.True(schema.Properties.ContainsKey("foo")); + Assert.True(exceptionSchema.Properties.ContainsKey("InnerException")); } } } diff --git a/src/NJsonSchema.Tests/Generation/InheritanceTests.cs b/src/NJsonSchema.Tests/Generation/InheritanceTests.cs index 9b1157e12..e7eb9a9c8 100644 --- a/src/NJsonSchema.Tests/Generation/InheritanceTests.cs +++ b/src/NJsonSchema.Tests/Generation/InheritanceTests.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.Threading.Tasks; @@ -89,9 +88,9 @@ public async Task When_generating_type_with_inheritance_then_allOf_has_one_item( var schema = await JsonSchema4.FromTypeAsync(); //// Assert - Assert.NotNull(schema.ActualProperties["Class"]); + Assert.NotNull(schema.Properties["Class"]); - Assert.Equal(2, schema.AllOf.Count); + Assert.Equal(1, schema.AllOf.Count); Assert.Contains(schema.Definitions, d => d.Key == "Person"); Assert.NotNull(schema.AllOf.First().ActualSchema.Properties["Name"]); } @@ -299,45 +298,10 @@ public async Task Existing_non_string_property_cant_be_discriminant() //// Arrange //// Act - Task GetSchema() => JsonSchema4.FromTypeAsync(); + Task getSchema() => JsonSchema4.FromTypeAsync(); //// Assert - await Assert.ThrowsAsync(GetSchema); - } - - public class Foo - { - public Bar Bar { get; set; } - } - - public class Bar : Dictionary - { - public string Baz { get; set; } - } - - [Fact] - public async Task When_class_inherits_from_dictionary_then_allOf_contains_base_dictionary_schema_and_actual_schema() - { - //// Arrange - var settings = new JsonSchemaGeneratorSettings - { - SchemaType = SchemaType.OpenApi3 - }; - - //// Act - var schema = await JsonSchema4.FromTypeAsync(settings); - var json = schema.ToJson(); - - //// Assert - var bar = schema.Definitions["Bar"]; - - Assert.Equal(2, bar.AllOf.Count); - - Assert.Equal(bar.AllOf.Last(), bar.ActualTypeSchema); - Assert.Equal(bar.AllOf.First(), bar.InheritedSchema); - - Assert.True(bar.AllOf.First().IsDictionary); // base class (dictionary) - Assert.True(bar.AllOf.Last().ActualProperties.Any()); // actual class + await Assert.ThrowsAsync(getSchema); } } } diff --git a/src/NJsonSchema/Generation/JsonSchemaGenerator.cs b/src/NJsonSchema/Generation/JsonSchemaGenerator.cs index 6335cfb4d..1947bc34e 100644 --- a/src/NJsonSchema/Generation/JsonSchemaGenerator.cs +++ b/src/NJsonSchema/Generation/JsonSchemaGenerator.cs @@ -146,7 +146,9 @@ public virtual async Task GenerateAsync(Type type, IEnumerableGenerates the properties for the given type and schema. + /// The type of the schema type. /// The types. - /// The type description. /// The properties /// The schema resolver. /// The task. - protected virtual async Task GenerateObjectAsync(Type type, - JsonTypeDescription typeDescription, JsonSchema4 schema, JsonSchemaResolver schemaResolver) + protected virtual async Task GenerateObjectAsync( + Type type, TSchemaType schema, JsonSchemaResolver schemaResolver) + where TSchemaType : JsonSchema4, new() { schemaResolver.AddSchema(type, false, schema); - var rootSchema = schema; - - var hasInheritance = await GenerateInheritanceAsync(type, schema, schemaResolver).ConfigureAwait(false); - if (hasInheritance) - { - var actualSchema = new JsonSchema4(); - schema.AllOf.Add(actualSchema); - schema = actualSchema; - } - typeDescription.ApplyType(schema); - schema.Description = await type.GetTypeInfo().GetDescriptionAsync(type.GetTypeInfo().GetCustomAttributes()).ConfigureAwait(false); - schema.AllowAdditionalProperties = false; schema.IsAbstract = type.GetTypeInfo().IsAbstract; - await GeneratePropertiesAsync(type, schema, schemaResolver).ConfigureAwait(false); + await GeneratePropertiesAndInheritanceAsync(type, schema, schemaResolver).ConfigureAwait(false); await ApplyAdditionalPropertiesAsync(type, schema, schemaResolver).ConfigureAwait(false); - GenerateInheritanceDiscriminator(type, rootSchema); - if (Settings.GenerateKnownTypes) await GenerateKnownTypesAsync(type, schemaResolver).ConfigureAwait(false); @@ -521,7 +510,7 @@ private async Task GenerateDictionaryAsync(TSchemaType schema, Type schema.AllowAdditionalProperties = true; } - private async Task GeneratePropertiesAsync(Type type, JsonSchema4 schema, JsonSchemaResolver schemaResolver) + private async Task GeneratePropertiesAndInheritanceAsync(Type type, JsonSchema4 schema, JsonSchemaResolver schemaResolver) { #if !LEGACY var propertiesAndFields = type.GetTypeInfo() @@ -614,6 +603,8 @@ private async Task GeneratePropertiesAsync(Type type, JsonSchema4 schema, JsonSc await LoadPropertyOrFieldAsync(property, info, type, schema, schemaResolver).ConfigureAwait(false); } } + + await GenerateInheritanceAsync(type, schema, schemaResolver).ConfigureAwait(false); } /// Gets the properties of the given type or null to take all properties. @@ -665,7 +656,7 @@ private async Task AddKnownTypeAsync(Type type, JsonSchemaResolver schemaResolve await GenerateAsync(type, schemaResolver).ConfigureAwait(false); } - private async Task GenerateInheritanceAsync(Type type, JsonSchema4 schema, JsonSchemaResolver schemaResolver) + private async Task GenerateInheritanceAsync(Type type, JsonSchema4 schema, JsonSchemaResolver schemaResolver) { var baseType = type.GetTypeInfo().BaseType; if (baseType != null && baseType != typeof(object) && baseType != typeof(ValueType)) @@ -678,12 +669,7 @@ private async Task GenerateInheritanceAsync(Type type, JsonSchema4 schema, { var typeDescription = Settings.ReflectionService.GetDescription(baseType, null, Settings); if (!typeDescription.IsDictionary && !type.IsArray) - { - await GeneratePropertiesAsync(baseType, schema, schemaResolver).ConfigureAwait(false); - await GenerateInheritanceAsync(baseType, schema, schemaResolver).ConfigureAwait(false); - - GenerateInheritanceDiscriminator(baseType, schema); - } + await GeneratePropertiesAndInheritanceAsync(baseType, schema, schemaResolver).ConfigureAwait(false); } else { @@ -701,8 +687,6 @@ private async Task GenerateInheritanceAsync(Type type, JsonSchema4 schema, } else schema.AllOf.Add(baseSchema); - - return true; } } } @@ -716,18 +700,12 @@ private async Task GenerateInheritanceAsync(Type type, JsonSchema4 schema, #endif { var typeDescription = Settings.ReflectionService.GetDescription(i, null, Settings); - if (!typeDescription.IsDictionary && !type.IsArray && - !typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(i.GetTypeInfo())) - { - await GeneratePropertiesAsync(i, schema, schemaResolver).ConfigureAwait(false); - await GenerateInheritanceAsync(i, schema, schemaResolver).ConfigureAwait(false); - - GenerateInheritanceDiscriminator(i, schema); - } + if (!typeDescription.IsDictionary && !type.IsArray && !typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(i.GetTypeInfo())) + await GeneratePropertiesAndInheritanceAsync(i, schema, schemaResolver).ConfigureAwait(false); } } - return false; + GenerateInheritanceDiscriminator(type, schema); } private void GenerateInheritanceDiscriminator(Type type, JsonSchema4 schema) @@ -1024,15 +1002,15 @@ private void ApplyRangeAttribute(JsonSchema4 schema, IEnumerable pare { if (rangeAttribute.OperandType == typeof(double)) { - var minimum = (double)Convert.ChangeType(rangeAttribute.Minimum, typeof(double)); + var minimum = (double) Convert.ChangeType(rangeAttribute.Minimum, typeof(double)); if (minimum > double.MinValue) { - schema.Minimum = (decimal)minimum; + schema.Minimum = (decimal) minimum; } } else { - var minimum = (decimal)Convert.ChangeType(rangeAttribute.Minimum, typeof(decimal)); + var minimum = (decimal) Convert.ChangeType(rangeAttribute.Minimum, typeof(decimal)); if (minimum > decimal.MinValue) { schema.Minimum = minimum; @@ -1044,15 +1022,15 @@ private void ApplyRangeAttribute(JsonSchema4 schema, IEnumerable pare { if (rangeAttribute.OperandType == typeof(double)) { - var maximum = (double)Convert.ChangeType(rangeAttribute.Maximum, typeof(double)); + var maximum = (double) Convert.ChangeType(rangeAttribute.Maximum, typeof(double)); if (maximum < double.MaxValue) { - schema.Maximum = (decimal)maximum; + schema.Maximum = (decimal) maximum; } } else { - var maximum = (decimal)Convert.ChangeType(rangeAttribute.Maximum, typeof(decimal)); + var maximum = (decimal) Convert.ChangeType(rangeAttribute.Maximum, typeof(decimal)); if (maximum < decimal.MaxValue) { schema.Maximum = maximum; diff --git a/src/NJsonSchema/Infrastructure/XmlDocumentationExtensions.cs b/src/NJsonSchema/Infrastructure/XmlDocumentationExtensions.cs index d8047a017..4100d4aaa 100644 --- a/src/NJsonSchema/Infrastructure/XmlDocumentationExtensions.cs +++ b/src/NJsonSchema/Infrastructure/XmlDocumentationExtensions.cs @@ -463,11 +463,7 @@ private static string RemoveLineBreakWhiteSpaces(string documentation) private static string GetMemberElementName(dynamic member) { char prefixCode; - - var memberName = member is Type memberType && !string.IsNullOrEmpty(memberType.FullName) ? - memberType.FullName : - member.DeclaringType.FullName + "." + member.Name; - + string memberName = member is Type ? ((Type)member).FullName : (member.DeclaringType.FullName + "." + member.Name); switch ((string)member.MemberType.ToString()) { case "Constructor": diff --git a/src/NJsonSchema/JsonSchema4.Reference.cs b/src/NJsonSchema/JsonSchema4.Reference.cs index 646bc88c5..89028c263 100644 --- a/src/NJsonSchema/JsonSchema4.Reference.cs +++ b/src/NJsonSchema/JsonSchema4.Reference.cs @@ -8,10 +8,8 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; using System.Linq; using Newtonsoft.Json; -using NJsonSchema.Collections; using NJsonSchema.References; namespace NJsonSchema @@ -28,18 +26,7 @@ public partial class JsonSchema4 : JsonReferenceBase, IJsonReferenc /// Cyclic references detected. /// The schema reference path has not been resolved. [JsonIgnore] - public virtual JsonSchema4 ActualTypeSchema - { - get - { - if (AllOf.Count > 1 && AllOf.Count(s => !s.HasReference && !s.IsDictionary) == 1) - { - return AllOf.First(s => !s.HasReference && !s.IsDictionary); - } - - return OneOf.FirstOrDefault(o => !o.IsNullable(SchemaType.JsonSchema))?.ActualSchema ?? ActualSchema; - } - } + public virtual JsonSchema4 ActualTypeSchema => OneOf.FirstOrDefault(o => !o.IsNullable(SchemaType.JsonSchema))?.ActualSchema ?? ActualSchema; /// Gets a value indicating whether this is a schema reference ($ref or ). [JsonIgnore]