-
Notifications
You must be signed in to change notification settings - Fork 4.8k
/
ConfigurationBindingGenerator.Emitter.cs
97 lines (83 loc) · 3.7 KB
/
ConfigurationBindingGenerator.Emitter.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
89
90
91
92
93
94
95
96
97
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.CodeAnalysis;
using SourceGenerators;
namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
public sealed partial class ConfigurationBindingGenerator : IIncrementalGenerator
{
private sealed partial class Emitter
{
private readonly InterceptorInfo _interceptorInfo;
private readonly BindingHelperInfo _bindingHelperInfo;
private readonly TypeIndex _typeIndex;
private readonly bool _emitEnumParseMethod;
private readonly bool _emitGenericParseEnum;
private readonly bool _emitThrowIfNullMethod;
private readonly SourceWriter _writer = new();
public Emitter(SourceGenerationSpec sourceGenSpec)
{
_interceptorInfo = sourceGenSpec.InterceptorInfo;
_bindingHelperInfo = sourceGenSpec.BindingHelperInfo;
_typeIndex = new TypeIndex(sourceGenSpec.ConfigTypes);
_emitEnumParseMethod = sourceGenSpec.EmitEnumParseMethod;
_emitGenericParseEnum = sourceGenSpec.EmitGenericParseEnum;
_emitThrowIfNullMethod = sourceGenSpec.EmitThrowIfNullMethod;
}
public void Emit(SourceProductionContext context)
{
if (!ShouldEmitMethods(MethodsToGen.Any))
{
return;
}
_writer.WriteLine("""
// <auto-generated/>
#nullable enable
#pragma warning disable CS0612, CS0618 // Suppress warnings about [Obsolete] member usage in generated code.
""");
EmitInterceptsLocationAttrDecl();
EmitStartBlock($"namespace {ProjectName}");
EmitUsingStatements();
_writer.WriteLine();
EmitStartBlock($$"""
{{Expression.GeneratedCodeAnnotation}}
file static class {{Identifier.BindingExtensions}}
""");
EmitBindingExtensions_IConfiguration();
EmitBindingExtensions_OptionsBuilder();
EmitBindingExtensions_IServiceCollection();
EmitCoreBindingHelpers();
EmitEndBlock(); // BindingExtensions class
EmitEndBlock(); // Binding namespace.
context.AddSource($"{Identifier.BindingExtensions}.g.cs", _writer.ToSourceText());
}
private void EmitInterceptsLocationAttrDecl()
{
_writer.WriteLine();
_writer.WriteLine($$"""
namespace System.Runtime.CompilerServices
{
using System;
using System.CodeDom.Compiler;
{{Expression.GeneratedCodeAnnotation}}
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
file sealed class InterceptsLocationAttribute : Attribute
{
public InterceptsLocationAttribute(string filePath, int line, int column)
{
}
}
}
""");
_writer.WriteLine();
}
private void EmitUsingStatements()
{
foreach (string @namespace in _bindingHelperInfo.Namespaces)
{
_writer.WriteLine($"using {@namespace};");
}
}
}
}
}