-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathEvil.cs
88 lines (76 loc) · 3.19 KB
/
Evil.cs
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
76
77
78
79
80
81
82
83
84
85
86
87
88
using System.Diagnostics.CodeAnalysis;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Text;
namespace NetJsonAOT.Generators;
// thank you to https://isadorasophia.com/articles/serialization/#6
// for this dastardly plan
internal static class Evil
{
public static void RunJsonNetSourceGenerator(
Action<string, SourceText> addSource, Compilation compilation,
params SourceText[] sources)
{
ParseOptions options;
if (compilation is CSharpCompilation { SyntaxTrees.Length: > 0 } csharpCompilation)
{
options = csharpCompilation.SyntaxTrees[0].Options;
}
else
{
options = CSharpParseOptions.Default.WithLanguageVersion(
LanguageVersion.Latest);
}
// Add all sources to our compilation.
foreach (var sourceText in sources)
{
var syntaxTree = SyntaxFactory.ParseSyntaxTree(sourceText, options);
compilation = compilation.AddSyntaxTrees(syntaxTree);
}
if (!TryGetJsonNetSourceGenerator(out var jsonGenerator))
return;
GeneratorDriver driver = CSharpGeneratorDriver.Create(jsonGenerator);
driver = driver.RunGenerators(compilation);
var driverResult = driver.GetRunResult();
foreach (var result in driverResult.Results)
{
foreach (var source in result.GeneratedSources)
{
Console.WriteLine("--------------------");
Console.WriteLine($"JSON GENERATED {source.HintName}\n{source.SourceText}\n");
Console.WriteLine("--------------------\n\n");
addSource("_" + source.HintName, source.SourceText);
}
}
}
private static bool TryGetJsonNetSourceGenerator([NotNullWhen(true)] out ISourceGenerator? jsonGenerator)
{
const string rootNamespace = "System.Text.Json";
const string sourceGenerationNamespace = rootNamespace + ".SourceGeneration";
const string sourceGeneratorFullTypeName = sourceGenerationNamespace + ".JsonSourceGenerator";
var assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(
a => a.FullName.Contains(sourceGenerationNamespace));
if(assembly is null)
{
Console.Error.WriteLine($"Unable to find {sourceGenerationNamespace} assembly");
jsonGenerator = null;
return false;
}
Type? textJsonForbiddenImporterType;
try
{
textJsonForbiddenImporterType = assembly.GetType(sourceGeneratorFullTypeName);
}
catch (Exception e)
{
Console.Error.WriteLine($"Unable to find {sourceGeneratorFullTypeName} generator: {e}");
jsonGenerator = null;
return false;
}
// See declaration of type at
// https://github.com/dotnet/runtime/blob/c5bead63f8386f716b8ddd909c93086b3546efed/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Roslyn4.0.cs
jsonGenerator = ((IIncrementalGenerator)Activator.CreateInstance(textJsonForbiddenImporterType))
.AsSourceGenerator();
return true;
}
}