Skip to content

Commit

Permalink
Merge branch 'master' into Add-option-to-explicitly-exclude-types-fro…
Browse files Browse the repository at this point in the history
…m-schema
  • Loading branch information
RicoSuter committed Jun 12, 2024
2 parents 79a760f + 4c76ebd commit f2d5659
Show file tree
Hide file tree
Showing 56 changed files with 465 additions and 243 deletions.
69 changes: 41 additions & 28 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,31 +1,44 @@
<Project>
<PropertyGroup>
<VersionPrefix>11.0.0</VersionPrefix>

<Authors>Rico Suter</Authors>
<Copyright>Copyright © Rico Suter, 2022</Copyright>

<SignAssembly>True</SignAssembly>
<AssemblyOriginatorKeyFile>../NJsonSchema.snk</AssemblyOriginatorKeyFile>

<PackageTags>json schema validation generator .net</PackageTags>
<PackageProjectUrl>http://NJsonSchema.org</PackageProjectUrl>
<Description>JSON Schema reader, generator and validator for .NET</Description>
<PackageIcon>NuGetIcon.png</PackageIcon>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<Company />
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<DebugSymbols>True</DebugSymbols>

<LangVersion>latest</LangVersion>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Nullable>enable</Nullable>

<UseArtifactsOutput>true</UseArtifactsOutput>

</PropertyGroup>
<PropertyGroup>
<VersionPrefix>11.0.0</VersionPrefix>

<Authors>Rico Suter</Authors>
<Copyright>Copyright © Rico Suter, 2022</Copyright>

<SignAssembly>True</SignAssembly>
<AssemblyOriginatorKeyFile>../NJsonSchema.snk</AssemblyOriginatorKeyFile>

<PackageTags>json schema validation generator .net</PackageTags>
<PackageProjectUrl>http://NJsonSchema.org</PackageProjectUrl>
<Description>JSON Schema reader, generator and validator for .NET</Description>
<PackageIcon>NuGetIcon.png</PackageIcon>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<Company />
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<DebugSymbols>True</DebugSymbols>

<LangVersion>latest</LangVersion>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Nullable>enable</Nullable>

<UseArtifactsOutput>true</UseArtifactsOutput>

</PropertyGroup>

<PropertyGroup Label="Analyzer settings">
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<AnalysisLevel>latest-Recommended</AnalysisLevel>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<!--
[CA1200] Avoid using cref tags with a prefix
[CA1510] Use 'ArgumentNullException.ThrowIfNull' instead of explicitly throwing a new exception instance
[CA1716] rename parameter property so that it no longer conflicts with the reserved language keyword
[CA1720] Identifier 'xxx' contains type name
-->
<NoWarn>$(NoWarn);CA1200;CA1510;CA1716;CA1720</NoWarn>
</PropertyGroup>

</Project>
14 changes: 7 additions & 7 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="BenchmarkDotNet" Version="0.13.9" />
<PackageVersion Include="Fluid.Core" Version="2.5.0" />
<PackageVersion Include="Fluid.Core" Version="2.9.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.2" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.0.1" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.7.2" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageVersion Include="Namotion.Reflection" Version="3.1.1" />
<PackageVersion Include="NBench" Version="2.0.1" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
Expand All @@ -18,13 +18,13 @@
<PackageVersion Include="System.ComponentModel.Annotations" Version="4.4.0" />
<PackageVersion Include="System.Text.Json" Version="4.7.2" />
<PackageVersion Include="Verify.XUnit" Version="14.7.0" />
<PackageVersion Include="xunit" Version="2.5.3" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.5.3" />
<PackageVersion Include="YamlDotNet" Version="13.7.1" />
<PackageVersion Include="xunit" Version="2.8.0" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.0" />
<PackageVersion Include="YamlDotNet" Version="15.1.4" />
</ItemGroup>
<ItemGroup>
<GlobalPackageReference Include="GitHubActionsTestLogger" Version="2.3.3" />
<GlobalPackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" />
<GlobalPackageReference Include="PolySharp" Version="1.13.2" />
<GlobalPackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
<GlobalPackageReference Include="PolySharp" Version="1.14.1" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
namespace NJsonSchema.Annotations;

/// <summary>Interface to add an extension data property to a class or property, implementation needs to inherit from System.Attribute.</summary>
#pragma warning disable CA1711 // Rename type name IJsonSchemaExtensionDataAttribute so that it does not end in 'Attribute'
public interface IJsonSchemaExtensionDataAttribute
#pragma warning restore CA1711
{
/// <summary>Gets the extension data.</summary>
IReadOnlyDictionary<string, object> ExtensionData { get; }
Expand Down
1 change: 1 addition & 0 deletions src/NJsonSchema.Benchmark/NJsonSchema.Benchmark.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<NoWarn>$(NoWarn),xUnit1013</NoWarn>
<SignAssembly>false</SignAssembly>
<Nullable>disable</Nullable>
<EnableNETAnalyzers>false</EnableNETAnalyzers>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn),1587,1998,1591,618,SYSLIB0012</NoWarn>
<Nullable>disable</Nullable>
<EnableNETAnalyzers>false</EnableNETAnalyzers>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,5 +245,48 @@ public async Task When_generating_from_json_schema_string_property_with_date_or_
Assert.Contains("public string Required { get; set; } = default!;", code);
Assert.Contains("public string? Optional { get; set; } = default!;", code);
}

[Fact]
public async Task
When_generating_from_json_schema_string_property_with_reference_is_optional_and_GenerateNullableOptionalProperties_is_set_then_CSharp_property()
{
//// Arrange
var schemaJson = @"
{
""type"": ""object"",
""required"": [
""required""
],
""properties"": {
""required"": { ""$ref"": ""#/$defs/requiredString"" },
""optional"": { ""$ref"": ""#/$defs/optionalString"" }
},
""$defs"": {
""requiredString"": { ""type"": ""string"" },
""optionalString"": { ""type"": ""string"" }
}
}
";

var schema = await JsonSchema.FromJsonAsync(schemaJson);

//// Act
var generator = new CSharpGenerator(schema, new CSharpGeneratorSettings
{
ClassStyle = CSharpClassStyle.Poco,
SchemaType = SchemaType.OpenApi3,
DateType = "string",
DateTimeType = "string",
TimeType = "string",
TimeSpanType = "string",
GenerateNullableReferenceTypes = true,
GenerateOptionalPropertiesAsNullable = true
});
var code = generator.GenerateFile("MyClass");

//// Assert
Assert.Contains("public string Required { get; set; } = default!;", code);
Assert.Contains("public string? Optional { get; set; } = default!;", code);
}
}
}
4 changes: 2 additions & 2 deletions src/NJsonSchema.CodeGeneration.CSharp/CSharpGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,13 @@ public override IEnumerable<CodeArtifact> GenerateTypes()
}

/// <inheritdoc />
protected override string GenerateFile(IEnumerable<CodeArtifact> artifactCollection)
protected override string GenerateFile(IEnumerable<CodeArtifact> artifacts)
{
var model = new FileTemplateModel
{
Namespace = Settings.Namespace ?? string.Empty,
GenerateNullableReferenceTypes = Settings.GenerateNullableReferenceTypes,
TypesCode = artifactCollection.Concatenate()
TypesCode = artifacts.Concatenate()
};

var template = Settings.TemplateFactory.CreateTemplate("CSharp", "File", model);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public static class CSharpJsonSerializerGenerator
public static string GenerateJsonSerializerParameterCode(CSharpGeneratorSettings settings, IEnumerable<string>? additionalJsonConverters)
{
var jsonConverters = GetJsonConverters(settings, additionalJsonConverters);
var hasJsonConverters = jsonConverters.Any();
var hasJsonConverters = jsonConverters.Count > 0;

return GenerateForJsonLibrary(settings, jsonConverters, hasJsonConverters);
}
Expand Down Expand Up @@ -95,24 +95,17 @@ private static string GenerateForJsonLibrary(CSharpGeneratorSettings settings, L

private static string GenerateConverters(List<string> jsonConverters, CSharpJsonLibrary jsonLibrary)
{
if (jsonConverters.Any())
if (jsonConverters.Count > 0)
{
switch (jsonLibrary)
return jsonLibrary switch
{
case CSharpJsonLibrary.NewtonsoftJson:
return "new Newtonsoft.Json.JsonConverter[] { " + string.Join(", ", jsonConverters.Select(c => "new " + c + "()")) + " }";

case CSharpJsonLibrary.SystemTextJson:
return "new System.Text.Json.Serialization.JsonConverter[] { " + string.Join(", ", jsonConverters.Select(c => "new " + c + "()")) + " }";

default: // TODO: possibly add more json converters
return string.Empty;
}
}
else
{
return string.Empty;
CSharpJsonLibrary.NewtonsoftJson => "new Newtonsoft.Json.JsonConverter[] { " + string.Join(", ", jsonConverters.Select(c => "new " + c + "()")) + " }",
CSharpJsonLibrary.SystemTextJson => "new System.Text.Json.Serialization.JsonConverter[] { " + string.Join(", ", jsonConverters.Select(c => "new " + c + "()")) + " }",
_ => string.Empty
};
}

return string.Empty;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace NJsonSchema.CodeGeneration.CSharp
/// <summary>Generates the property name for a given CSharp <see cref="JsonSchemaProperty"/>.</summary>
public sealed class CSharpPropertyNameGenerator : IPropertyNameGenerator
{
private static readonly char[] _reservedFirstPassChars = { '"', '\'', '@', '?', '!', '$', '[', ']', '(', ')', '.', '=', '+' };
private static readonly char[] _reservedFirstPassChars = { '"', '\'', '@', '?', '!', '$', '[', ']', '(', ')', '.', '=', '+', '|' };
private static readonly char[] _reservedSecondPassChars = { '*', ':', '-', '#', '&' };

/// <summary>Generates the property name.</summary>
Expand All @@ -35,7 +35,8 @@ public string Generate(JsonSchemaProperty property)
.Replace(")", string.Empty)
.Replace(".", "-")
.Replace("=", "-")
.Replace("+", "plus");
.Replace("+", "plus")
.Replace("|", "_");
}

name = ConversionUtilities.ConvertToUpperCamelCase(name, true);
Expand All @@ -53,4 +54,4 @@ public string Generate(JsonSchemaProperty property)
return name;
}
}
}
}
16 changes: 8 additions & 8 deletions src/NJsonSchema.CodeGeneration.CSharp/CSharpTypeResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,6 @@ public string Resolve(JsonSchema schema, bool isNullable, string? typeNameHint,
throw new ArgumentNullException(nameof(schema));
}

schema = GetResolvableSchema(schema);

if (schema == ExceptionSchema)
{
return "System.Exception";
}

// Primitive schemas (no new type)
if (Settings.GenerateOptionalPropertiesAsNullable &&
schema is JsonSchemaProperty property &&
Expand All @@ -75,6 +68,13 @@ schema is JsonSchemaProperty property &&
isNullable = true;
}

schema = GetResolvableSchema(schema);

if (schema == ExceptionSchema)
{
return "System.Exception";
}

var markAsNullableType = Settings.GenerateNullableReferenceTypes && isNullable;

if (schema.ActualTypeSchema.IsAnyType &&
Expand Down Expand Up @@ -217,7 +217,7 @@ private static string ResolveBoolean(bool isNullable)
return isNullable ? "bool?" : "bool";
}

private string ResolveInteger(JsonSchema schema, bool isNullable, string? typeNameHint)
private static string ResolveInteger(JsonSchema schema, bool isNullable, string? typeNameHint)
{
if (schema.Format == JsonFormatStrings.Byte)
{
Expand Down
10 changes: 5 additions & 5 deletions src/NJsonSchema.CodeGeneration.CSharp/CSharpValueGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,11 @@ public CSharpValueGenerator(CSharpGeneratorSettings settings)
if (schema.Type.IsArray() ||
schema.Type.IsObject())
{
targetType = !string.IsNullOrEmpty(_settings.DictionaryInstanceType) && targetType.StartsWith(_settings.DictionaryType + "<")
targetType = !string.IsNullOrEmpty(_settings.DictionaryInstanceType) && targetType.StartsWith(_settings.DictionaryType + "<", StringComparison.Ordinal)
? _settings.DictionaryInstanceType + targetType.Substring(_settings.DictionaryType.Length)
: targetType;

targetType = !string.IsNullOrEmpty(_settings.ArrayInstanceType) && targetType.StartsWith(_settings.ArrayType + "<")
targetType = !string.IsNullOrEmpty(_settings.ArrayInstanceType) && targetType.StartsWith(_settings.ArrayType + "<", StringComparison.Ordinal)
? _settings.ArrayInstanceType + targetType.Substring(_settings.ArrayType.Length)
: targetType;

Expand All @@ -93,11 +93,11 @@ public override string GetNumericValue(JsonObjectType type, object value, string
switch (format)
{
case JsonFormatStrings.Byte:
return "(byte)" + Convert.ToByte(value).ToString(CultureInfo.InvariantCulture);
return "(byte)" + Convert.ToByte(value, CultureInfo.InvariantCulture).ToString(CultureInfo.InvariantCulture);
case JsonFormatStrings.Integer:
return Convert.ToInt32(value).ToString(CultureInfo.InvariantCulture);
return Convert.ToInt32(value, CultureInfo.InvariantCulture).ToString(CultureInfo.InvariantCulture);
case JsonFormatStrings.Long:
return Convert.ToInt64(value) + "L";
return Convert.ToInt64(value, CultureInfo.InvariantCulture) + "L";
case JsonFormatStrings.Double:
return ConvertNumberToString(value) + "D";
case JsonFormatStrings.Float:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
// <author>Rico Suter, mail@rsuter.com</author>
//-----------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using NJsonSchema.CodeGeneration.Models;
Expand Down Expand Up @@ -145,7 +146,7 @@ public ClassTemplateModel(string typeName, CSharpGeneratorSettings settings,
_schema?.InheritsSchema(_resolver.ExceptionSchema) == true;

/// <summary>Gets a value indicating whether to use the DateFormatConverter.</summary>
public bool UseDateFormatConverter => _settings.DateType.StartsWith("System.DateTime");
public bool UseDateFormatConverter => _settings.DateType.StartsWith("System.DateTime", StringComparison.Ordinal);

/// <summary>Gets or sets the access modifier of generated classes and interfaces.</summary>
public string TypeAccessModifier => _settings.TypeAccessModifier;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

using NJsonSchema.Annotations;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using NJsonSchema.CodeGeneration.Models;

Expand Down Expand Up @@ -78,8 +79,8 @@ public IEnumerable<EnumerationItemModel> Enums
{
Name = _settings.EnumNameGenerator.Generate(i, name, value, _schema),
Value = value.ToString(),
InternalValue = valueInt64.ToString(),
InternalFlagValue = valueInt64.ToString()
InternalValue = valueInt64.ToString(CultureInfo.InvariantCulture),
InternalFlagValue = valueInt64.ToString(CultureInfo.InvariantCulture)
});
}
else
Expand All @@ -89,7 +90,7 @@ public IEnumerable<EnumerationItemModel> Enums
Name = _settings.EnumNameGenerator.Generate(i, name, value, _schema),
Value = value.ToString(),
InternalValue = value.ToString(),
InternalFlagValue = (1 << i).ToString()
InternalFlagValue = (1 << i).ToString(CultureInfo.InvariantCulture)
});
}
}
Expand All @@ -102,8 +103,8 @@ public IEnumerable<EnumerationItemModel> Enums
{
Name = _settings.EnumNameGenerator.Generate(i, name, value, _schema),
Value = value.ToString(),
InternalValue = i.ToString(),
InternalFlagValue = (1 << i).ToString()
InternalValue = i.ToString(CultureInfo.InvariantCulture),
InternalFlagValue = (1 << i).ToString(CultureInfo.InvariantCulture)
});
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Loading

0 comments on commit f2d5659

Please sign in to comment.