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

Optimize type resolving #1629

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,21 @@ jobs:
name: windows-latest
runs-on: windows-latest
steps:
- uses: actions/checkout@v1
- name: Cache .nuke/temp, ~/.nuget/packages
uses: actions/cache@v2
- uses: actions/checkout@v3
- name: 'Cache: .nuke/temp, ~/.nuget/packages'
uses: actions/cache@v3
with:
path: |
.nuke/temp
~/.nuget/packages
key: ${{ runner.os }}-${{ hashFiles('global.json', 'src/**/*.csproj', 'src/**/package.json') }}
- name: Run './build.cmd Compile Test Pack Publish'
- name: 'Run: Compile, Test, Pack, Publish'
run: ./build.cmd Compile Test Pack Publish
env:
NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
MYGET_API_KEY: ${{ secrets.MYGET_API_KEY }}
- uses: actions/upload-artifact@v1
- name: 'Publish: artifacts'
uses: actions/upload-artifact@v3
with:
name: artifacts
path: artifacts
8 changes: 4 additions & 4 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ jobs:
name: windows-latest
runs-on: windows-latest
steps:
- uses: actions/checkout@v1
- name: Cache .nuke/temp, ~/.nuget/packages
uses: actions/cache@v2
- uses: actions/checkout@v3
- name: 'Cache: .nuke/temp, ~/.nuget/packages'
uses: actions/cache@v3
with:
path: |
.nuke/temp
~/.nuget/packages
key: ${{ runner.os }}-${{ hashFiles('global.json', 'src/**/*.csproj', 'src/**/package.json') }}
- name: Run './build.cmd Compile Test Pack'
- name: 'Run: Compile, Test, Pack'
run: ./build.cmd Compile Test Pack
9 changes: 5 additions & 4 deletions .nuke/build.schema.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Build Schema",
"$ref": "#/definitions/build",
"title": "Build Schema",
"definitions": {
"build": {
"type": "object",
Expand Down Expand Up @@ -29,6 +29,7 @@
"AppVeyor",
"AzurePipelines",
"Bamboo",
"Bitbucket",
"Bitrise",
"GitHubActions",
"GitLab",
Expand All @@ -44,15 +45,15 @@
},
"MyGetApiKey": {
"type": "string",
"default": "Secrets must be entered via 'nuke :secret [profile]'"
"default": "Secrets must be entered via 'nuke :secrets [profile]'"
},
"NoLogo": {
"type": "boolean",
"description": "Disables displaying the NUKE logo"
},
"NuGetApiKey": {
"type": "string",
"default": "Secrets must be entered via 'nuke :secret [profile]'"
"default": "Secrets must be entered via 'nuke :secrets [profile]'"
},
"Partition": {
"type": "string",
Expand Down Expand Up @@ -120,4 +121,4 @@
}
}
}
}
}
9 changes: 7 additions & 2 deletions build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ $TempDirectory = "$PSScriptRoot\\.nuke\temp"

$DotNetGlobalFile = "$PSScriptRoot\\global.json"
$DotNetInstallUrl = "https://dot.net/v1/dotnet-install.ps1"
$DotNetChannel = "Current"
$DotNetChannel = "STS"

$env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE = 1
$env:DOTNET_CLI_TELEMETRY_OPTOUT = 1
Expand Down Expand Up @@ -63,7 +63,12 @@ else {
$env:DOTNET_EXE = "$DotNetDirectory\dotnet.exe"
}

Write-Output "Microsoft (R) .NET Core SDK version $(& $env:DOTNET_EXE --version)"
Write-Output "Microsoft (R) .NET SDK version $(& $env:DOTNET_EXE --version)"

if (Test-Path env:NUKE_ENTERPRISE_TOKEN) {
& $env:DOTNET_EXE nuget remove source "nuke-enterprise" > $null
& $env:DOTNET_EXE nuget add source "https://f.feedz.io/nuke/enterprise/nuget" --name "nuke-enterprise" --username "PAT" --password $env:NUKE_ENTERPRISE_TOKEN > $null
}

ExecSafe { & $env:DOTNET_EXE build $BuildProjectFile /nodeReuse:false /p:UseSharedCompilation=false -nologo -clp:NoSummary --verbosity quiet }
ExecSafe { & $env:DOTNET_EXE run --project $BuildProjectFile --no-build -- $BuildArguments }
9 changes: 7 additions & 2 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ TEMP_DIRECTORY="$SCRIPT_DIR//.nuke/temp"

DOTNET_GLOBAL_FILE="$SCRIPT_DIR//global.json"
DOTNET_INSTALL_URL="https://dot.net/v1/dotnet-install.sh"
DOTNET_CHANNEL="Current"
DOTNET_CHANNEL="STS"

export DOTNET_CLI_TELEMETRY_OPTOUT=1
export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
Expand Down Expand Up @@ -56,7 +56,12 @@ else
export DOTNET_EXE="$DOTNET_DIRECTORY/dotnet"
fi

echo "Microsoft (R) .NET Core SDK version $("$DOTNET_EXE" --version)"
echo "Microsoft (R) .NET SDK version $("$DOTNET_EXE" --version)"

if [[ ! -z ${NUKE_ENTERPRISE_TOKEN+x} && "NUKE_ENTERPRISE_TOKEN" != "" ]]; then
"$DOTNET_EXE" nuget remove source "nuke-enterprise" &>/dev/null || true
"$DOTNET_EXE" nuget add source "https://f.feedz.io/nuke/enterprise/nuget" --name "nuke-enterprise" --username "PAT" --password "$NUKE_ENTERPRISE_TOKEN" --store-password-in-clear-text &>/dev/null || true
fi

"$DOTNET_EXE" build "$BUILD_PROJECT_FILE" /nodeReuse:false /p:UseSharedCompilation=false -nologo -clp:NoSummary --verbosity quiet
"$DOTNET_EXE" run --project "$BUILD_PROJECT_FILE" --no-build -- "$@"
2 changes: 1 addition & 1 deletion build/_build.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Nuke.Common" Version="7.0.2" />
<PackageReference Include="Nuke.Common" Version="7.0.6" />
<PackageDownload Include="NuGet.CommandLine" Version="[5.11.0]" />
</ItemGroup>

Expand Down
30 changes: 30 additions & 0 deletions src/NJsonSchema.Benchmark/CSharpTypeResolverBenchmark.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
using NJsonSchema.CodeGeneration.CSharp;

namespace NJsonSchema.Benchmark;

[MemoryDiagnoser]
public class CSharpTypeResolverBenchmark
{
private Dictionary<string, JsonSchema> _definitions;
private CSharpGeneratorSettings _settings;

[GlobalSetup]
public async Task Setup()
{
var json = await JsonSchemaBenchmark.ReadJson();
var schema = await JsonSchema.FromJsonAsync(json);
_definitions = schema.Definitions.ToDictionary(p => p.Key, p => p.Value);
_settings = new CSharpGeneratorSettings();
}

[Benchmark]
public void RegisterSchemaDefinitions()
{
var resolver = new CSharpTypeResolver(_settings, exceptionSchema: null);
resolver.RegisterSchemaDefinitions(_definitions);
}
}
Original file line number Diff line number Diff line change
@@ -1,29 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<IsPackable>false</IsPackable>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn),1587,1998,1591,618,SYSLIB0012</NoWarn>
<TargetFramework>net6.0</TargetFramework>
<IsPackable>false</IsPackable>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn),1587,1998,1591,618,SYSLIB0012</NoWarn>
</PropertyGroup>

<ItemGroup>
<Content Include="References\*.json" CopyToOutputDirectory="Always" />
<Content Include="References\*.json" CopyToOutputDirectory="Always" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.11.0" Condition="'$(TargetFramework)' == 'net6.0'" />
<PackageReference Condition="'$(TargetFramework)' == 'net6.0'" Include="System.ComponentModel.Annotations" Version="4.4.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.11.0" Condition="'$(TargetFramework)' == 'net6.0'" />
<PackageReference Condition="'$(TargetFramework)' == 'net6.0'" Include="System.ComponentModel.Annotations" Version="4.4.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\NJsonSchema.CodeGeneration.CSharp\NJsonSchema.CodeGeneration.CSharp.csproj" />
<ProjectReference Include="..\NJsonSchema.CodeGeneration\NJsonSchema.CodeGeneration.csproj" />
<ProjectReference Include="..\NJsonSchema.NewtonsoftJson\NJsonSchema.NewtonsoftJson.csproj" />
<ProjectReference Include="..\NJsonSchema\NJsonSchema.csproj" />
<ProjectReference Include="..\NJsonSchema.CodeGeneration.CSharp\NJsonSchema.CodeGeneration.CSharp.csproj" />
<ProjectReference Include="..\NJsonSchema.NewtonsoftJson\NJsonSchema.NewtonsoftJson.csproj" />
</ItemGroup>

</Project>
6 changes: 3 additions & 3 deletions src/NJsonSchema.CodeGeneration.CSharp/CSharpTypeResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ private string ResolveArrayOrTuple(JsonSchema schema)
{
var itemTypeNameHint = (schema as JsonSchemaProperty)?.Name;
var itemType = Resolve(schema.Item, schema.Item.IsNullable(Settings.SchemaType), itemTypeNameHint);
return string.Format(Settings.ArrayType + "<{0}>", itemType);
return $"{Settings.ArrayType}<{itemType}>";
}

if (schema.Items != null && schema.Items.Count > 0)
Expand All @@ -279,7 +279,7 @@ private string ResolveArrayOrTuple(JsonSchema schema)
.Select(i => Resolve(i, i.IsNullable(Settings.SchemaType), null))
.ToArray();

return string.Format("System.Tuple<" + string.Join(", ", tupleTypes) + ">");
return $"System.Tuple<{string.Join(", ", tupleTypes)}>";
}

return Settings.ArrayType + "<object>";
Expand All @@ -289,7 +289,7 @@ private string ResolveDictionary(JsonSchema schema)
{
var valueType = ResolveDictionaryValueType(schema, "object");
var keyType = ResolveDictionaryKeyType(schema, "string");
return string.Format(Settings.DictionaryType + "<{0}, {1}>", keyType, valueType);
return $"{Settings.DictionaryType}<{keyType}, {valueType}>";
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,8 @@
<EmbeddedResource Include="Templates\*.liquid" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\NJsonSchema.CodeGeneration\NJsonSchema.CodeGeneration.csproj" />
<ProjectReference Include="..\NJsonSchema\NJsonSchema.csproj" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@
<ItemGroup>
<ProjectReference Include="..\NJsonSchema.CodeGeneration.CSharp\NJsonSchema.CodeGeneration.CSharp.csproj" />
<ProjectReference Include="..\NJsonSchema.CodeGeneration.TypeScript\NJsonSchema.CodeGeneration.TypeScript.csproj" />
<ProjectReference Include="..\NJsonSchema.CodeGeneration\NJsonSchema.CodeGeneration.csproj" />
<ProjectReference Include="..\NJsonSchema.NewtonsoftJson\NJsonSchema.NewtonsoftJson.csproj" />
<ProjectReference Include="..\NJsonSchema\NJsonSchema.csproj" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@

<ItemGroup>
<ProjectReference Include="..\NJsonSchema.CodeGeneration.TypeScript\NJsonSchema.CodeGeneration.TypeScript.csproj" />
<ProjectReference Include="..\NJsonSchema.CodeGeneration\NJsonSchema.CodeGeneration.csproj" />
<ProjectReference Include="..\NJsonSchema.NewtonsoftJson\NJsonSchema.NewtonsoftJson.csproj" />
<ProjectReference Include="..\NJsonSchema\NJsonSchema.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,8 @@
<EmbeddedResource Include="Templates\File.ParseDateOnly.liquid" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\NJsonSchema.CodeGeneration\NJsonSchema.CodeGeneration.csproj" />
<ProjectReference Include="..\NJsonSchema\NJsonSchema.csproj" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -314,15 +314,15 @@ private string ResolveArrayOrTuple(JsonSchema schema, string typeNameHint, bool
// is TypeUnion
if (itemTypes.Count > 1)
{
itemType = string.Format("({0})", itemType);
itemType = $"({itemType})";
}

return string.Format("{0}[]", itemType);
return $"{itemType}[]";
}
else
{
var itemType = prefix + Resolve(schema.Item, true, typeNameHint);
return string.Format("{0}[]", GetNullableItemType(schema, itemType)); // TODO: Make typeNameHint singular if possible
return $"{GetNullableItemType(schema, itemType)}[]"; // TODO: Make typeNameHint singular if possible
}
}

Expand All @@ -332,7 +332,7 @@ private string ResolveArrayOrTuple(JsonSchema schema, string typeNameHint, bool
.Select(s => GetNullableItemType(s, Resolve(s, false, null)))
.ToArray();

return string.Format("[" + string.Join(", ", tupleTypes) + "]");
return $"[{string.Join(", ", tupleTypes)}]";
}

return "any[]";
Expand All @@ -342,7 +342,7 @@ private string GetNullableItemType(JsonSchema schema, string itemType)
{
if (Settings.SupportsStrictNullChecks && schema.Item.IsNullable(Settings.SchemaType))
{
return string.Format("({0} | {1})", itemType, Settings.NullValue.ToString().ToLowerInvariant());
return $"({itemType} | {Settings.NullValue.ToString().ToLowerInvariant()})";
}

return itemType;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

<ItemGroup>
<PackageReference Include="Fluid.Core" Version="2.4.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>

<ItemGroup>
Expand Down
12 changes: 6 additions & 6 deletions src/NJsonSchema.CodeGeneration/TypeResolverBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public abstract class TypeResolverBase
{
private readonly CodeGeneratorSettingsBase _settings;
internal readonly Dictionary<JsonSchema, string> _generatedTypeNames = new();
private readonly HashSet<string> _reservedTypeNames = new();

/// <summary>Initializes a new instance of the <see cref="TypeResolverBase" /> class.</summary>
/// <param name="settings">The settings.</param>
Expand Down Expand Up @@ -55,9 +56,9 @@ public virtual string GetOrGenerateTypeName(JsonSchema schema, string typeNameHi

if (!_generatedTypeNames.TryGetValue(schema, out var typeNames))
{
var reservedTypeNames = new HashSet<string>(_generatedTypeNames.Values);
typeNames = _settings.TypeNameGenerator.Generate(schema, typeNameHint, reservedTypeNames);
typeNames = _settings.TypeNameGenerator.Generate(schema, typeNameHint, _reservedTypeNames);
_generatedTypeNames[schema] = typeNames;
_reservedTypeNames.Add(typeNames);
}

return typeNames;
Expand Down Expand Up @@ -87,7 +88,7 @@ public void RegisterSchemaDefinitions(IDictionary<string, JsonSchema> definition
public virtual JsonSchema RemoveNullability(JsonSchema schema)
{
// TODO: Method on JsonSchema4?
return schema.OneOf.FirstOrDefault(o => !o.IsNullable(SchemaType.JsonSchema)) ?? schema;
return schema.OneOf.FirstOrDefault(static o => !o.IsNullable(SchemaType.JsonSchema)) ?? schema;
}

/// <summary>Gets the actual schema (i.e. when not referencing a type schema or it is inlined)
Expand Down Expand Up @@ -141,10 +142,9 @@ protected string ResolveDictionaryValueType(JsonSchema schema, string fallbackTy

if (schema.AllowAdditionalProperties == false && schema.PatternProperties.Any())
{
var valueTypes = schema.PatternProperties
var valueTypes = new HashSet<string>(schema.PatternProperties
.Select(p => Resolve(p.Value, p.Value.IsNullable(_settings.SchemaType), null))
.Distinct()
.ToList();
);

if (valueTypes.Count == 1)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@

<ItemGroup>
<ProjectReference Include="..\NJsonSchema.NewtonsoftJson\NJsonSchema.NewtonsoftJson.csproj" />
<ProjectReference Include="..\NJsonSchema\NJsonSchema.csproj" />
</ItemGroup>

</Project>
Loading
Loading