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

Use Incremental Source Generators #591

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
4 changes: 4 additions & 0 deletions Source/Schema.NET.Pending/Schema.NET.Pending.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,8 @@
<Compile Include="../Common/*.*" />
</ItemGroup>

<ItemGroup Label="Source Generation">
<AdditionalFiles Include="../../Data/*.*" LinkBase="Data" />
</ItemGroup>

</Project>
4 changes: 4 additions & 0 deletions Source/Schema.NET/Schema.NET.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,8 @@
<Compile Include="../Common/*.*" />
</ItemGroup>

<ItemGroup Label="Source Generation">
<AdditionalFiles Include="../../Data/*.*" LinkBase="Data" />
</ItemGroup>

</Project>
3 changes: 1 addition & 2 deletions Tools/Schema.NET.Tool/Repositories/ISchemaRepository.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
namespace Schema.NET.Tool.Repositories;

using System.Collections.Generic;
using System.Threading.Tasks;
using Schema.NET.Tool.Models;

public interface ISchemaRepository
{
Task<(IEnumerable<SchemaClass> Classes, IEnumerable<SchemaProperty> Properties, IEnumerable<SchemaEnumerationValue> EnumerationValues)> GetObjectsAsync();
(IEnumerable<SchemaClass> Classes, IEnumerable<SchemaProperty> Properties, IEnumerable<SchemaEnumerationValue> EnumerationValues) GetObjects();
}
21 changes: 7 additions & 14 deletions Tools/Schema.NET.Tool/Repositories/SchemaRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,23 @@ namespace Schema.NET.Tool.Repositories;

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Text;
using Schema.NET.Tool.Models;

public class SchemaRepository : ISchemaRepository
{
private readonly Stream stream;
private readonly SourceText jsonLd;

public SchemaRepository(Stream stream) => this.stream = stream;
public SchemaRepository(SourceText jsonLd) => this.jsonLd = jsonLd;

public async Task<(IEnumerable<SchemaClass> Classes, IEnumerable<SchemaProperty> Properties, IEnumerable<SchemaEnumerationValue> EnumerationValues)> GetObjectsAsync()
public (IEnumerable<SchemaClass> Classes, IEnumerable<SchemaProperty> Properties, IEnumerable<SchemaEnumerationValue> EnumerationValues) GetObjects()
{
var schemaObjects = await this.GetSchemaObjectsAsync().ConfigureAwait(false) ??
var schemaObjects = Deserialize<List<SchemaObject>>(this.jsonLd.ToString(), new SchemaPropertyJsonConverter()) ??
throw new InvalidOperationException("No schema objects found.");

schemaObjects = schemaObjects.ToArray();

var schemaClasses = schemaObjects.OfType<SchemaClass>().ToArray();

foreach (var schemaClass in schemaClasses)
Expand All @@ -34,17 +31,13 @@ public class SchemaRepository : ISchemaRepository
schemaObjects.OfType<SchemaEnumerationValue>().ToArray());
}

public async Task<IEnumerable<SchemaObject>?> GetSchemaObjectsAsync() =>
await DeserializeAsync<List<SchemaObject>>(this.stream, new SchemaPropertyJsonConverter())
.ConfigureAwait(false);

private static async Task<T?> DeserializeAsync<T>(Stream jsonStream, JsonConverter converter)
private static T? Deserialize<T>(string json, JsonConverter converter)
{
var options = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
};
options.Converters.Add(converter);
return await JsonSerializer.DeserializeAsync<T>(jsonStream, options).ConfigureAwait(false);
return JsonSerializer.Deserialize<T>(json, options);
}
}
1 change: 0 additions & 1 deletion Tools/Schema.NET.Tool/Schema.NET.Tool.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Include="../../Data/*.*" LinkBase="Data" />
</ItemGroup>

</Project>
44 changes: 24 additions & 20 deletions Tools/Schema.NET.Tool/SchemaSourceGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,31 +1,41 @@
namespace Schema.NET.Tool;

using System;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
using Schema.NET.Tool.CustomOverrides;
using Schema.NET.Tool.GeneratorModels;
using Schema.NET.Tool.Repositories;
using Schema.NET.Tool.Services;

[Generator]
public class SchemaSourceGenerator : ISourceGenerator
public class SchemaSourceGenerator : IIncrementalGenerator
{
private const string SchemaDataName = "Schema.NET.Tool.Data.schemaorg-all-https.jsonld";
private const string SchemaDataName = "schemaorg-all-https.jsonld";

public void Initialize(GeneratorInitializationContext context)
public void Initialize(IncrementalGeneratorInitializationContext context)
{
var schemaJsonLdDataFile = context.AdditionalTextsProvider
.Where(static text => text.Path.EndsWith(SchemaDataName, StringComparison.OrdinalIgnoreCase))
.Collect();

var configuration = context.AnalyzerConfigOptionsProvider
.Select((provider, _) => provider.GlobalOptions);

context.RegisterSourceOutput(configuration.Combine(schemaJsonLdDataFile), Generate);
}

public void Execute(GeneratorExecutionContext context)
private static void Generate(SourceProductionContext context, (AnalyzerConfigOptions Options, ImmutableArray<AdditionalText> AdditionalText) data)
{
var schemaDataStream = Assembly
.GetExecutingAssembly()
.GetManifestResourceStream(SchemaDataName) ??
throw new InvalidOperationException($"Schema data file '{SchemaDataName}' not found.");
var schemaJsonLdDataFile = data.AdditionalText.SingleOrDefault() ??
throw new InvalidOperationException($"Schema data file '{SchemaDataName}' not configured.");

var schemaJsonLdData = schemaJsonLdDataFile.GetText(context.CancellationToken) ??
throw new InvalidOperationException($"Unable to read schema data file '{SchemaDataName}'.");

var schemaRepository = new SchemaRepository(schemaDataStream);
var schemaRepository = new SchemaRepository(schemaJsonLdData);
var schemaService = new SchemaService(
new IClassOverride[]
{
Expand All @@ -36,12 +46,9 @@ public void Execute(GeneratorExecutionContext context)
},
Array.Empty<IEnumerationOverride>(),
schemaRepository,
IncludePendingSchemaObjects(context));

#pragma warning disable VSTHRD002 // Avoid problematic synchronous waits
var schemaObjects = schemaService.GetObjectsAsync().GetAwaiter().GetResult();
#pragma warning restore VSTHRD002 // Avoid problematic synchronous waits
IncludePendingSchemaObjects(data.Options));

var schemaObjects = schemaService.GetObjects();
if (schemaObjects is not null)
{
foreach (var schemaObject in schemaObjects)
Expand All @@ -61,12 +68,9 @@ public void Execute(GeneratorExecutionContext context)
}
}

private static bool IncludePendingSchemaObjects(GeneratorExecutionContext context)
{
var configuration = context.AnalyzerConfigOptions.GlobalOptions;
return configuration.TryGetValue($"build_property.IncludePendingSchemaObjects", out var value) &&
private static bool IncludePendingSchemaObjects(AnalyzerConfigOptions options) =>
options.TryGetValue($"build_property.IncludePendingSchemaObjects", out var value) &&
value.Equals("true", StringComparison.OrdinalIgnoreCase);
}

private static string RenderClass(GeneratorSchemaClass schemaClass)
{
Expand Down
8 changes: 3 additions & 5 deletions Tools/Schema.NET.Tool/Services/SchemaService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ namespace Schema.NET.Tool.Services;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Schema.NET.Tool.CustomOverrides;
using Schema.NET.Tool.GeneratorModels;
using Schema.NET.Tool.Repositories;
Expand All @@ -32,11 +31,10 @@ public SchemaService(
this.includePending = includePending;
}

public async Task<IEnumerable<GeneratorSchemaObject>> GetObjectsAsync()
public IEnumerable<GeneratorSchemaObject> GetObjects()
{
var (schemaClasses, schemaProperties, schemaValues) = await this.schemaRepository
.GetObjectsAsync()
.ConfigureAwait(false);
var (schemaClasses, schemaProperties, schemaValues) = this.schemaRepository
.GetObjects();

var isEnumMap = new HashSet<string>(
schemaClasses.Where(c => c.IsEnum).Select(c => c.Label),
Expand Down