Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Implement oneOf inheritance #1295

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/NJsonSchema.CodeGeneration.CSharp/CSharpGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public CSharpGenerator(object rootObject)
/// <param name="rootObject">The root object to search for all JSON Schemas.</param>
/// <param name="settings">The generator settings.</param>
public CSharpGenerator(object rootObject, CSharpGeneratorSettings settings)
: this(rootObject, settings, new CSharpTypeResolver(settings))
: this(rootObject, settings, new CSharpTypeResolver(rootObject, settings))
{
}

Expand Down Expand Up @@ -108,13 +108,13 @@ protected override CodeArtifact GenerateType(JsonSchema schema, string typeNameH
}
else
{
return GenerateClass(schema, typeName);
return GenerateClass(schema, typeName, typeNameHint);
}
}

private CodeArtifact GenerateClass(JsonSchema schema, string typeName)
private CodeArtifact GenerateClass(JsonSchema schema, string typeName, string typeNameHint)
{
var model = new ClassTemplateModel(typeName, Settings, _resolver, schema, RootObject);
var model = new ClassTemplateModel(typeName, typeNameHint, Settings, _resolver, schema, RootObject);

RenamePropertyWithSameNameAsClass(typeName, model.Properties);

Expand Down
13 changes: 9 additions & 4 deletions src/NJsonSchema.CodeGeneration.CSharp/CSharpTypeResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,24 @@ namespace NJsonSchema.CodeGeneration.CSharp
/// <summary>Manages the generated types and converts JSON types to CSharp types. </summary>
public class CSharpTypeResolver : TypeResolverBase
{
private readonly object _rootObject;

/// <summary>Initializes a new instance of the <see cref="CSharpTypeResolver"/> class.</summary>
/// <param name="rootObject">The root object.</param>
/// <param name="settings">The generator settings.</param>
public CSharpTypeResolver(CSharpGeneratorSettings settings)
: this(settings, null)
public CSharpTypeResolver(object rootObject, CSharpGeneratorSettings settings)
: this(rootObject, settings, null)
{
}

/// <summary>Initializes a new instance of the <see cref="CSharpTypeResolver"/> class.</summary>
/// <param name="rootObject">The root object.</param>
/// <param name="settings">The generator settings.</param>
/// <param name="exceptionSchema">The exception type schema.</param>
public CSharpTypeResolver(CSharpGeneratorSettings settings, JsonSchema exceptionSchema)
public CSharpTypeResolver(object rootObject, CSharpGeneratorSettings settings, JsonSchema exceptionSchema)
: base(settings)
{
_rootObject = rootObject;
Settings = settings;
ExceptionSchema = exceptionSchema;
}
Expand Down Expand Up @@ -78,7 +83,7 @@ public string Resolve(JsonSchema schema, bool isNullable, string typeNameHint, b
var markAsNullableType = Settings.GenerateNullableReferenceTypes && isNullable;

if (schema.ActualTypeSchema.IsAnyType &&
schema.InheritedSchema == null && // not in inheritance hierarchy
schema.GetInheritedSchema(_rootObject) == null && // not in inheritance hierarchy
schema.AllOf.Count == 0 &&
!Types.Keys.Contains(schema) &&
!schema.HasReference)
Expand Down
25 changes: 10 additions & 15 deletions src/NJsonSchema.CodeGeneration.CSharp/Models/ClassTemplateModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,23 @@ public class ClassTemplateModel : ClassTemplateModelBase
{
private readonly CSharpTypeResolver _resolver;
private readonly JsonSchema _schema;
private readonly object _rootObject;
private readonly CSharpGeneratorSettings _settings;

/// <summary>Initializes a new instance of the <see cref="ClassTemplateModel"/> class.</summary>
/// <param name="typeName">Name of the type.</param>
/// <param name="discriminatorName">The name to compare the discriminator against.</param>
/// <param name="settings">The settings.</param>
/// <param name="resolver">The resolver.</param>
/// <param name="schema">The schema.</param>
/// <param name="rootObject">The root object.</param>
public ClassTemplateModel(string typeName, CSharpGeneratorSettings settings,
public ClassTemplateModel(string typeName, string discriminatorName, CSharpGeneratorSettings settings,
CSharpTypeResolver resolver, JsonSchema schema, object rootObject)
: base(resolver, schema, rootObject)
: base(resolver, schema, rootObject, discriminatorName)
{
_resolver = resolver;
_schema = schema;
_rootObject = rootObject;
_settings = settings;

ClassName = typeName;
Expand All @@ -39,9 +42,10 @@ public class ClassTemplateModel : ClassTemplateModelBase
.Select(property => new PropertyModel(this, property, _resolver, _settings))
.ToArray();

if (schema.InheritedSchema != null)
var inheritedSchema = schema.GetInheritedSchema(rootObject);
if (inheritedSchema != null)
{
BaseClass = new ClassTemplateModel(BaseClassName, settings, resolver, schema.InheritedSchema, rootObject);
BaseClass = new ClassTemplateModel(BaseClassName, discriminatorName, settings, resolver, inheritedSchema, rootObject);
AllProperties = Properties.Concat(BaseClass.AllProperties).ToArray();
}
else
Expand Down Expand Up @@ -102,12 +106,6 @@ public class ClassTemplateModel : ClassTemplateModelBase
/// <summary>Gets a value indicating whether to render ToJson() and FromJson() methods.</summary>
public bool GenerateJsonMethods => _settings.GenerateJsonMethods;

/// <summary>Gets a value indicating whether the class has discriminator property.</summary>
public bool HasDiscriminator => !string.IsNullOrEmpty(_schema.ActualDiscriminator);

/// <summary>Gets the discriminator property name.</summary>
public string Discriminator => _schema.ActualDiscriminator;

/// <summary>Gets a value indicating whether this class represents a tuple.</summary>
public bool IsTuple => _schema.ActualTypeSchema.IsTuple;

Expand All @@ -116,11 +114,8 @@ public class ClassTemplateModel : ClassTemplateModelBase
.Select(i => _resolver.Resolve(i, i.IsNullable(_settings.SchemaType), string.Empty, false))
.ToArray();

/// <summary>Gets a value indicating whether the class has a parent class.</summary>
public bool HasInheritance => _schema.InheritedTypeSchema != null;

/// <summary>Gets the base class name.</summary>
public string BaseClassName => HasInheritance ? _resolver.Resolve(_schema.InheritedTypeSchema, false, string.Empty, false)
public string BaseClassName => HasInheritance ? _resolver.Resolve(_schema.GetInheritedSchema(_rootObject), false, string.Empty, false)
.Replace(_settings.ArrayType + "<", _settings.ArrayBaseType + "<")
.Replace(_settings.DictionaryType + "<", _settings.DictionaryBaseType + "<") : null;

Expand All @@ -129,7 +124,7 @@ public class ClassTemplateModel : ClassTemplateModelBase

/// <summary>Gets a value indicating whether the class inherits from exception.</summary>
public bool InheritsExceptionSchema => _resolver.ExceptionSchema != null &&
_schema?.InheritsSchema(_resolver.ExceptionSchema) == true;
_schema?.InheritsSchema(_resolver.ExceptionSchema, _rootObject) == true;

/// <summary>Gets a value indicating whether to use the DateFormatConverter.</summary>
public bool UseDateFormatConverter => _settings.DateType.StartsWith("System.Date");
Expand Down
68 changes: 34 additions & 34 deletions src/NJsonSchema.CodeGeneration.Tests/DefaultValueGeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,19 @@ namespace NJsonSchema.CodeGeneration.Tests
{
public class DefaultValueGeneratorTests
{
private readonly CSharpValueGenerator _csharpGenerator;
private readonly CSharpTypeResolver _csharpTypeResolver;
private readonly CSharpGeneratorSettings _csharpSettings;
private readonly CSharpValueGenerator _csharpValueGenerator;

private readonly TypeScriptValueGenerator _typescriptGenerator;
private readonly TypeScriptGeneratorSettings _typescriptSettings;
private readonly TypeScriptValueGenerator _typescriptValueGenerator;

public DefaultValueGeneratorTests()
{
var csharpSettings = new CSharpGeneratorSettings();
_csharpTypeResolver = new CSharpTypeResolver(csharpSettings);
_csharpGenerator = new CSharpValueGenerator(csharpSettings);
_csharpSettings = new CSharpGeneratorSettings();
_csharpValueGenerator = new CSharpValueGenerator(_csharpSettings);

_typescriptSettings = new TypeScriptGeneratorSettings();
_typescriptGenerator = new TypeScriptValueGenerator(_typescriptSettings);
_typescriptValueGenerator = new TypeScriptValueGenerator(_typescriptSettings);
}

[Fact]
Expand All @@ -34,10 +33,10 @@ public void When_schema_has_default_value_of_int_it_is_generated_in_CSharp_and_T
Default = (int)6
};

var typescriptTypeResolver = new TypeScriptTypeResolver(_typescriptSettings);
var typescriptTypeResolver = new TypeScriptTypeResolver(schema, _typescriptSettings);

var csharpValue = _csharpGenerator.GetDefaultValue(schema, true, "int", "int", true, _csharpTypeResolver);
var typescriptValue = _typescriptGenerator.GetDefaultValue(schema, true, "int", "int", true, typescriptTypeResolver);
var csharpValue = _csharpValueGenerator.GetDefaultValue(schema, true, "int", "int", true, new CSharpTypeResolver(schema, _csharpSettings));
var typescriptValue = _typescriptValueGenerator.GetDefaultValue(schema, true, "int", "int", true, typescriptTypeResolver);

//// Assert
Assert.Equal("6", csharpValue);
Expand All @@ -57,10 +56,10 @@ public void When_schema_has_default_value_of_long_it_is_generated_in_CSharp_and_
Default = 6000000000L
};

var typescriptTypeResolver = new TypeScriptTypeResolver(_typescriptSettings);
var typescriptTypeResolver = new TypeScriptTypeResolver(schema, _typescriptSettings);

var csharpValue = _csharpGenerator.GetDefaultValue(schema, true, "long", "long", true, _csharpTypeResolver);
var typescriptValue = _typescriptGenerator.GetDefaultValue(schema, true, "long", "long", true, typescriptTypeResolver);
var csharpValue = _csharpValueGenerator.GetDefaultValue(schema, true, "long", "long", true, new CSharpTypeResolver(schema, _csharpSettings));
var typescriptValue = _typescriptValueGenerator.GetDefaultValue(schema, true, "long", "long", true, typescriptTypeResolver);

//// Assert
Assert.Equal("6000000000L", csharpValue);
Expand All @@ -80,10 +79,10 @@ public void When_schema_has_default_value_of_double_it_is_generated_in_CSharp_an
Default = 1234.567F
};

var typescriptTypeResolver = new TypeScriptTypeResolver(_typescriptSettings);
var typescriptTypeResolver = new TypeScriptTypeResolver(schema, _typescriptSettings);

var csharpValue = _csharpGenerator.GetDefaultValue(schema, true, "double", "double", true, _csharpTypeResolver);
var typescriptValue = _typescriptGenerator.GetDefaultValue(schema, true, "double", "double", true, typescriptTypeResolver);
var csharpValue = _csharpValueGenerator.GetDefaultValue(schema, true, "double", "double", true, new CSharpTypeResolver(schema, _csharpSettings));
var typescriptValue = _typescriptValueGenerator.GetDefaultValue(schema, true, "double", "double", true, typescriptTypeResolver);

//// Assert
Assert.Equal("1234.567D", csharpValue);
Expand All @@ -102,10 +101,10 @@ public void When_schema_has_default_value_of_double_without_format_it_is_generat
Default = 1234.567F
};

var typescriptTypeResolver = new TypeScriptTypeResolver(_typescriptSettings);
var typescriptTypeResolver = new TypeScriptTypeResolver(schema, _typescriptSettings);

var csharpValue = _csharpGenerator.GetDefaultValue(schema, true, "double", "double", true, _csharpTypeResolver);
var typescriptValue = _typescriptGenerator.GetDefaultValue(schema, true, "double", "double", true, typescriptTypeResolver);
var csharpValue = _csharpValueGenerator.GetDefaultValue(schema, true, "double", "double", true, new CSharpTypeResolver(schema, _csharpSettings));
var typescriptValue = _typescriptValueGenerator.GetDefaultValue(schema, true, "double", "double", true, typescriptTypeResolver);

//// Assert
Assert.Equal("1234.567D", csharpValue);
Expand All @@ -125,10 +124,10 @@ public void When_schema_has_default_value_of_float_it_is_generated_in_CSharp_and
Default = 1234.567F
};

var typescriptTypeResolver = new TypeScriptTypeResolver(_typescriptSettings);
var typescriptTypeResolver = new TypeScriptTypeResolver(schema, _typescriptSettings);

var csharpValue = _csharpGenerator.GetDefaultValue(schema, true, "float", "float", true, _csharpTypeResolver);
var typescriptValue = _typescriptGenerator.GetDefaultValue(schema, true, "float", "float", true, typescriptTypeResolver);
var csharpValue = _csharpValueGenerator.GetDefaultValue(schema, true, "float", "float", true, new CSharpTypeResolver(schema, _csharpSettings));
var typescriptValue = _typescriptValueGenerator.GetDefaultValue(schema, true, "float", "float", true, typescriptTypeResolver);

//// Assert
Assert.Equal("1234.567F", csharpValue);
Expand All @@ -147,10 +146,10 @@ public void When_schema_has_default_value_of_bool_it_is_generated_in_CSharp_and_
Default = true
};

var typescriptTypeResolver = new TypeScriptTypeResolver(_typescriptSettings);
var typescriptTypeResolver = new TypeScriptTypeResolver(schema, _typescriptSettings);

var csharpValue = _csharpGenerator.GetDefaultValue(schema, true, "bool", "bool", true, _csharpTypeResolver);
var typescriptValue = _typescriptGenerator.GetDefaultValue(schema, true, "bool", "bool", true, typescriptTypeResolver);
var csharpValue = _csharpValueGenerator.GetDefaultValue(schema, true, "bool", "bool", true, new CSharpTypeResolver(schema, _csharpSettings));
var typescriptValue = _typescriptValueGenerator.GetDefaultValue(schema, true, "bool", "bool", true, typescriptTypeResolver);

//// Assert
Assert.Equal("true", csharpValue);
Expand All @@ -169,10 +168,10 @@ public void When_schema_has_default_value_of_string_it_is_generated_in_CSharp_an
Default = "test\\test\"test\r\ntest"
};

var typescriptTypeResolver = new TypeScriptTypeResolver(_typescriptSettings);
var typescriptTypeResolver = new TypeScriptTypeResolver(schema, _typescriptSettings);

var csharpValue = _csharpGenerator.GetDefaultValue(schema, true, "string", "string", true, _csharpTypeResolver);
var typescriptValue = _typescriptGenerator.GetDefaultValue(schema, true, "string", "string", true, typescriptTypeResolver);
var csharpValue = _csharpValueGenerator.GetDefaultValue(schema, true, "string", "string", true, new CSharpTypeResolver(schema, _csharpSettings));
var typescriptValue = _typescriptValueGenerator.GetDefaultValue(schema, true, "string", "string", true, typescriptTypeResolver);

//// Assert
Assert.Equal("\"test\\\\test\\\"test\\r\\ntest\"", csharpValue);
Expand All @@ -191,11 +190,6 @@ public string Generate(int index, string name, object value, JsonSchema schema)
public void When_schema_has_default_value_of_enum_it_is_generated_in_CSharp_and_TypeScript_correctly()
{
//// Arrange
var csharpSettings = new CSharpGeneratorSettings { EnumNameGenerator = new MyEnumNameGenerator(), Namespace = "Ns" };
var csharpGenerator = new CSharpValueGenerator(csharpSettings);
var csharpTypeResolver = new CSharpTypeResolver(csharpSettings);

//// Act
var schema = new JsonSchema()
{
Type = JsonObjectType.String,
Expand All @@ -207,9 +201,15 @@ public void When_schema_has_default_value_of_enum_it_is_generated_in_CSharp_and_
Default = "Bar"
};

var csharpSettings = new CSharpGeneratorSettings { EnumNameGenerator = new MyEnumNameGenerator(), Namespace = "Ns" };
var csharpGenerator = new CSharpValueGenerator(csharpSettings);
var csharpTypeResolver = new CSharpTypeResolver(schema, csharpSettings);

//// Act

var typescriptSettings = new TypeScriptGeneratorSettings { EnumNameGenerator = new MyEnumNameGenerator() };
var typescriptGenerator = new TypeScriptValueGenerator(typescriptSettings);
var typescriptTypeResolver = new TypeScriptTypeResolver(typescriptSettings);
var typescriptTypeResolver = new TypeScriptTypeResolver(schema, typescriptSettings);

var csharpValue = csharpGenerator.GetDefaultValue(schema, true, "MyEnum", "MyEnum", true, csharpTypeResolver);
var typescriptValue = typescriptGenerator.GetDefaultValue(schema, true, "MyEnum", "MyEnum", true, typescriptTypeResolver);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
using NJsonSchema.CodeGeneration.TypeScript;
using NJsonSchema.Converters;
using Xunit;

using System.IO;
using System.Reflection;
using System.CodeDom.Compiler;
Expand Down