-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathGeneratorBase.cs
More file actions
75 lines (65 loc) · 2.27 KB
/
GeneratorBase.cs
File metadata and controls
75 lines (65 loc) · 2.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// Copyright (c) ktsu.dev
// All rights reserved.
// Licensed under the MIT license.
namespace Semantics.SourceGenerators;
using System.Linq;
using System.Text.Json;
using ktsu.CodeBlocker;
using Microsoft.CodeAnalysis;
using Semantics.SourceGenerators.Templates;
public abstract class GeneratorBase<T>(string metadataFilename) : IIncrementalGenerator
{
public virtual void Initialize(IncrementalGeneratorInitializationContext context)
{
// Find the conversions metadata JSON file
IncrementalValuesProvider<string> metadataFiles = context.AdditionalTextsProvider
.Where(file => file.Path.EndsWith(metadataFilename, System.StringComparison.InvariantCulture))
.Select((file, cancellationToken) => file.GetText(cancellationToken)?.ToString() ?? "")
.Where(content => !string.IsNullOrEmpty(content));
// Generate code from metadata
context.RegisterSourceOutput(metadataFiles, (ctx, jsonContent) =>
{
if (string.IsNullOrEmpty(jsonContent))
{
return;
}
try
{
JsonSerializerOptions options = new()
{
PropertyNameCaseInsensitive = true
};
T metadata = JsonSerializer.Deserialize<T>(jsonContent, options) ??
throw new JsonException("Failed to deserialize metadata");
using CodeBlocker codeBlocker = CodeBlocker.Create();
Generate(ctx, metadata, codeBlocker);
}
catch (JsonException ex)
{
// Report JSON parsing error
DiagnosticDescriptor descriptor = new(
"CONV001",
"JSON parsing error",
"Failed to parse metadata JSON: {0}",
"SourceGenerator",
DiagnosticSeverity.Error,
isEnabledByDefault: true);
ctx.ReportDiagnostic(Diagnostic.Create(descriptor, Location.None, ex.Message));
}
});
}
protected abstract void Generate(SourceProductionContext context, T metadata, CodeBlocker codeBlocker);
protected static void WriteHeaderTo(CodeBlocker codeBlocker)
{
codeBlocker.WriteLine("// Copyright (c) ktsu.dev");
codeBlocker.WriteLine("// All rights reserved.");
codeBlocker.WriteLine("// Licensed under the MIT license.");
codeBlocker.WriteLine("// <auto-generated />");
codeBlocker.NewLine();
}
internal static void WriteSourceFileTo(CodeBlocker codeBlocker, SourceFileTemplate sourceFileTemplate)
{
WriteHeaderTo(codeBlocker);
codeBlocker.AddSourceFile(sourceFileTemplate);
}
}