Skip to content

Commit

Permalink
Use Incremental Source Generators
Browse files Browse the repository at this point in the history
  • Loading branch information
Turnerj authored and RehanSaeed committed May 22, 2023
1 parent 6d606c7 commit 4b0906f
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 42 deletions.
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 @@ -35,12 +45,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 @@ -60,12 +67,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

0 comments on commit 4b0906f

Please sign in to comment.