未验证 提交 7d9f506c 编写于 作者: G github-actions[bot] 提交者: GitHub

[release/8.0-preview7] Share SourceWriter between JSON & config binding generators (#89196)

* Share SourceWriter between JSON & config binding generators

* Fix failing test, clean up impl, and address feedback

---------
Co-authored-by: NLayomi Akinrinade <laakinri@microsoft.com>
Co-authored-by: NEric StJohn <ericstj@microsoft.com>
上级 854cc2ce
// Licensed to the .NET Foundation under one or more agreements. // Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license. // The .NET Foundation licenses this file to you under the MIT license.
using Microsoft.CodeAnalysis.Text; using System;
using System.Text;
using System.Diagnostics; using System.Diagnostics;
using Microsoft.CodeAnalysis.Text;
namespace System.Text.Json.SourceGeneration namespace SourceGenerators
{ {
internal sealed class SourceWriter internal sealed class SourceWriter
{ {
private const char IndentationChar = ' ';
private const int CharsPerIndentation = 4;
private readonly StringBuilder _sb = new(); private readonly StringBuilder _sb = new();
private int _indentation; private int _indentation;
public SourceWriter()
{
IndentationChar = ' ';
CharsPerIndentation = 4;
}
public SourceWriter(char indentationChar, int charsPerIndentation)
{
if (!char.IsWhiteSpace(indentationChar))
{
throw new ArgumentOutOfRangeException(nameof(indentationChar));
}
if (charsPerIndentation < 1)
{
throw new ArgumentOutOfRangeException(nameof(charsPerIndentation));
}
IndentationChar = indentationChar;
CharsPerIndentation = charsPerIndentation;
}
public char IndentationChar { get; }
public int CharsPerIndentation { get; }
public int Length => _sb.Length;
public int Indentation public int Indentation
{ {
get => _indentation; get => _indentation;
...@@ -88,6 +67,12 @@ public SourceText ToSourceText() ...@@ -88,6 +67,12 @@ public SourceText ToSourceText()
return SourceText.From(_sb.ToString(), Encoding.UTF8); return SourceText.From(_sb.ToString(), Encoding.UTF8);
} }
public void Reset()
{
_sb.Clear();
_indentation = 0;
}
private void AddIndentation() private void AddIndentation()
=> _sb.Append(IndentationChar, CharsPerIndentation * _indentation); => _sb.Append(IndentationChar, CharsPerIndentation * _indentation);
......
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
Link="Common\Interop\Linux\Interop.ProcFsStat.TryReadStatusFile.cs" /> Link="Common\Interop\Linux\Interop.ProcFsStat.TryReadStatusFile.cs" />
<Compile Include="$(CommonPath)Interop\Linux\os-release\Interop.OSReleaseFile.cs" <Compile Include="$(CommonPath)Interop\Linux\os-release\Interop.OSReleaseFile.cs"
Link="Common\Interop\Linux\os-release\Interop.OSReleaseFile.cs" /> Link="Common\Interop\Linux\os-release\Interop.OSReleaseFile.cs" />
<Compile Include="$(CommonPath)SourceGenerators\SourceWriter.cs"
Link="Common\SourceGenerators\SourceWriter.cs" />
<Compile Include="$(CommonPath)System\CharArrayHelpers.cs" <Compile Include="$(CommonPath)System\CharArrayHelpers.cs"
Link="Common\System\CharArrayHelpers.cs" /> Link="Common\System\CharArrayHelpers.cs" />
<Compile Include="$(CommonPath)System\StringExtensions.cs" <Compile Include="$(CommonPath)System\StringExtensions.cs"
...@@ -81,6 +83,7 @@ ...@@ -81,6 +83,7 @@
<Compile Include="Tests\Interop\cgroupsTests.cs" /> <Compile Include="Tests\Interop\cgroupsTests.cs" />
<Compile Include="Tests\Interop\procfsTests.cs" /> <Compile Include="Tests\Interop\procfsTests.cs" />
<Compile Include="Tests\Interop\OSReleaseTests.cs" /> <Compile Include="Tests\Interop\OSReleaseTests.cs" />
<Compile Include="Tests\SourceGenerators\SourceWriterTests.cs" />
<Compile Include="Tests\System\IO\PathInternal.Tests.cs" /> <Compile Include="Tests\System\IO\PathInternal.Tests.cs" />
<Compile Include="Tests\System\IO\StringParserTests.cs" /> <Compile Include="Tests\System\IO\StringParserTests.cs" />
<Compile Include="Tests\System\Net\HttpDateParserTests.cs" /> <Compile Include="Tests\System\Net\HttpDateParserTests.cs" />
...@@ -155,6 +158,9 @@ ...@@ -155,6 +158,9 @@
<Folder Include="System\Net\Sockets\" /> <Folder Include="System\Net\Sockets\" />
<Folder Include="System\Net\VirtualNetwork\" /> <Folder Include="System\Net\VirtualNetwork\" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="$(MicrosoftCodeAnalysisVersion_LatestVS)" PrivateAssets="all" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="$(CommonTestPath)StreamConformanceTests\StreamConformanceTests.csproj" /> <ProjectReference Include="$(CommonTestPath)StreamConformanceTests\StreamConformanceTests.csproj" />
</ItemGroup> </ItemGroup>
......
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using SourceGenerators;
using Xunit;
namespace Common.Tests
{
public sealed class SourceWriterTests
{
[Fact]
public void CanHandleVariousLineEndings()
{
string testTemplate = "public static void Main(){0}{{{1}\tConsole.WriteLine(\"Hello, world\");{2}}}";
SourceWriter writer = new();
CheckCanWrite(string.Format(testTemplate, "\n", "\n", "\n"));
CheckCanWrite(string.Format(testTemplate, "\r\n", "\r\n", "\r\n"));
CheckCanWrite(string.Format(testTemplate, "\n", "\r\n", "\n"));
// Regression test for https://github.com/dotnet/runtime/issues/88918.
CheckCanWrite(" global::Microsoft.Extensions.DependencyInjection.OptionsServiceCollectionExtensions.AddOptions(services);\r\n global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton<global::Microsoft.Extensions.Options.IOptionsChangeTokenSource<TOptions>>(services, new global::Microsoft.Extensions.Options.ConfigurationChangeTokenSource<TOptions>(name, configuration));\r\n return global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton<global::Microsoft.Extensions.Options.IConfigureOptions<TOptions>>(services, new global::Microsoft.Extensions.Options.ConfigureNamedOptions<TOptions>(name, obj => global::Microsoft.Extensions.Configuration.Binder.SourceGeneration.CoreBindingHelper.BindCoreUntyped(configuration, obj, typeof(TOptions), configureOptions)));\r\n}");
void CheckCanWrite(string source)
{
// No exception expected.
writer.WriteLine(source);
writer.Reset();
}
}
}
}
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
using System.Diagnostics; using System.Diagnostics;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
using SourceGenerators;
namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{ {
...@@ -36,17 +37,17 @@ public void Emit() ...@@ -36,17 +37,17 @@ public void Emit()
return; return;
} }
_writer.WriteBlock(""" _writer.WriteLine("""
// <auto-generated/> // <auto-generated/>
#nullable enable #nullable enable
#pragma warning disable CS0612, CS0618 // Suppress warnings about [Obsolete] member usage in generated code. #pragma warning disable CS0612, CS0618 // Suppress warnings about [Obsolete] member usage in generated code.
"""); """);
_writer.WriteBlankLine(); _writer.WriteLine();
_useFullyQualifiedNames = true; _useFullyQualifiedNames = true;
EmitBinder_ConfigurationBinder(); EmitBinder_Extensions_IConfiguration();
EmitBinder_Extensions_OptionsBuilder(); EmitBinder_Extensions_OptionsBuilder();
EmitBinder_Extensions_ServiceCollection(); EmitBinder_Extensions_IServiceCollection();
_useFullyQualifiedNames = false; _useFullyQualifiedNames = false;
Emit_CoreBindingHelper(); Emit_CoreBindingHelper();
...@@ -131,14 +132,16 @@ void EmitObjectInit(string objExpression, InitializationKind initKind) ...@@ -131,14 +132,16 @@ void EmitObjectInit(string objExpression, InitializationKind initKind)
if (!checkForNullSectionValue) if (!checkForNullSectionValue)
{ {
writeOnSuccess?.Invoke(parsedValueExpr); InvokeWriteOnSuccess();
} }
else else
{ {
_writer.WriteBlockStart($"if ({sectionValueExpr} is string {nonNull_StringValue_Identifier})"); EmitStartBlock($"if ({sectionValueExpr} is string {nonNull_StringValue_Identifier})");
writeOnSuccess?.Invoke(parsedValueExpr); InvokeWriteOnSuccess();
_writer.WriteBlockEnd(); EmitEndBlock();
} }
void InvokeWriteOnSuccess() => writeOnSuccess?.Invoke(parsedValueExpr);
} }
private bool EmitObjectInit(TypeSpec type, string memberAccessExpr, InitializationKind initKind, string configArgExpr) private bool EmitObjectInit(TypeSpec type, string memberAccessExpr, InitializationKind initKind, string configArgExpr)
...@@ -222,7 +225,7 @@ private void EmitCastToIConfigurationSection() ...@@ -222,7 +225,7 @@ private void EmitCastToIConfigurationSection()
exceptionTypeDisplayString = nameof(InvalidOperationException); exceptionTypeDisplayString = nameof(InvalidOperationException);
} }
_writer.WriteBlock($$""" _writer.WriteLine($$"""
if ({{Identifier.configuration}} is not {{sectionTypeDisplayString}} {{Identifier.section}}) if ({{Identifier.configuration}} is not {{sectionTypeDisplayString}} {{Identifier.section}})
{ {
throw new {{exceptionTypeDisplayString}}(); throw new {{exceptionTypeDisplayString}}();
...@@ -235,13 +238,13 @@ private void EmitIConfigurationHasValueOrChildrenCheck(bool voidReturn) ...@@ -235,13 +238,13 @@ private void EmitIConfigurationHasValueOrChildrenCheck(bool voidReturn)
string returnPostfix = voidReturn ? string.Empty : " null"; string returnPostfix = voidReturn ? string.Empty : " null";
string methodDisplayString = GetHelperMethodDisplayString(Identifier.HasValueOrChildren); string methodDisplayString = GetHelperMethodDisplayString(Identifier.HasValueOrChildren);
_writer.WriteBlock($$""" _writer.WriteLine($$"""
if (!{{methodDisplayString}}({{Identifier.configuration}})) if (!{{methodDisplayString}}({{Identifier.configuration}}))
{ {
return{{returnPostfix}}; return{{returnPostfix}};
} }
"""); """);
_writer.WriteBlankLine(); _writer.WriteLine();
} }
} }
} }
......
...@@ -14,7 +14,7 @@ private sealed partial class Emitter ...@@ -14,7 +14,7 @@ private sealed partial class Emitter
{ {
private bool ShouldEmitMethods(MethodsToGen_ConfigurationBinder methods) => (_sourceGenSpec.MethodsToGen_ConfigurationBinder & methods) != 0; private bool ShouldEmitMethods(MethodsToGen_ConfigurationBinder methods) => (_sourceGenSpec.MethodsToGen_ConfigurationBinder & methods) != 0;
private void EmitBinder_ConfigurationBinder() private void EmitBinder_Extensions_IConfiguration()
{ {
Debug.Assert(_sourceGenSpec.TypesForGen_ConfigurationBinder_BindMethods.Count <= 3 && Debug.Assert(_sourceGenSpec.TypesForGen_ConfigurationBinder_BindMethods.Count <= 3 &&
!_sourceGenSpec.TypesForGen_ConfigurationBinder_BindMethods.Keys.Any(overload => (overload & MethodsToGen_ConfigurationBinder.Bind) is 0)); !_sourceGenSpec.TypesForGen_ConfigurationBinder_BindMethods.Keys.Any(overload => (overload & MethodsToGen_ConfigurationBinder.Bind) is 0));
...@@ -25,13 +25,13 @@ private void EmitBinder_ConfigurationBinder() ...@@ -25,13 +25,13 @@ private void EmitBinder_ConfigurationBinder()
} }
_emitBlankLineBeforeNextStatement = false; _emitBlankLineBeforeNextStatement = false;
EmitRootBindingClassBlockStart(Identifier.GeneratedConfigurationBinder); EmitRootBindingClassStartBlock(Identifier.GeneratedConfigurationBinder);
EmitGetMethods(); EmitGetMethods();
EmitGetValueMethods(); EmitGetValueMethods();
EmitBindMethods_ConfigurationBinder(); EmitBindMethods_ConfigurationBinder();
_writer.WriteBlockEnd(); EmitEndBlock();
_emitBlankLineBeforeNextStatement = true; _emitBlankLineBeforeNextStatement = true;
} }
......
...@@ -129,11 +129,43 @@ private static class Identifier ...@@ -129,11 +129,43 @@ private static class Identifier
ShouldEmitMethods(MethodsToGen_Extensions_OptionsBuilder.Any) || ShouldEmitMethods(MethodsToGen_Extensions_OptionsBuilder.Any) ||
ShouldEmitMethods(MethodsToGen_Extensions_ServiceCollection.Any); ShouldEmitMethods(MethodsToGen_Extensions_ServiceCollection.Any);
/// <summary>
/// Starts a block of source code.
/// </summary>
/// <param name="source">Source to write after the open brace.</param>
public void EmitStartBlock(string? source = null)
{
if (source is not null)
{
_writer.WriteLine(source);
}
_writer.WriteLine("{");
_writer.Indentation++;
}
/// <summary>
/// Ends a block of source code.
/// </summary>
/// <param name="source">Source to write before the close brace.</param>
/// <param name="endBraceTrailingSource">Trailing source after the end brace, e.g. ";" to end an init statement.</param>
public void EmitEndBlock(string? source = null, string? endBraceTrailingSource = null)
{
if (source is not null)
{
_writer.WriteLine(source);
}
string endBlockSource = endBraceTrailingSource is null ? "}" : $"}}{endBraceTrailingSource}";
_writer.Indentation--;
_writer.WriteLine(endBlockSource);
}
private void EmitBlankLineIfRequired() private void EmitBlankLineIfRequired()
{ {
if (_emitBlankLineBeforeNextStatement) if (_emitBlankLineBeforeNextStatement)
{ {
_writer.WriteBlankLine(); _writer.WriteLine();
} }
_emitBlankLineBeforeNextStatement = true; _emitBlankLineBeforeNextStatement = true;
...@@ -153,14 +185,14 @@ private void EmitCheckForNullArgument_WithBlankLine(string paramName) ...@@ -153,14 +185,14 @@ private void EmitCheckForNullArgument_WithBlankLine(string paramName)
? "global::System.ArgumentNullException" ? "global::System.ArgumentNullException"
: "ArgumentNullException"; : "ArgumentNullException";
_writer.WriteBlock($$""" _writer.WriteLine($$"""
if ({{paramName}} is null) if ({{paramName}} is null)
{ {
throw new {{exceptionTypeDisplayString}}(nameof({{paramName}})); throw new {{exceptionTypeDisplayString}}(nameof({{paramName}}));
} }
"""); """);
_writer.WriteBlankLine(); _writer.WriteLine();
} }
private bool EmitInitException(TypeSpec type) private bool EmitInitException(TypeSpec type)
...@@ -176,14 +208,13 @@ private bool EmitInitException(TypeSpec type) ...@@ -176,14 +208,13 @@ private bool EmitInitException(TypeSpec type)
return false; return false;
} }
private void EmitRootBindingClassBlockStart(string className) private void EmitRootBindingClassStartBlock(string className)
{ {
EmitBlankLineIfRequired(); EmitBlankLineIfRequired();
_writer.WriteBlock($$""" EmitStartBlock($$"""
/// <summary>Generated helper providing an AOT and linking compatible implementation for configuration binding.</summary> /// <summary>Generated helper providing an AOT and linking compatible implementation for configuration binding.</summary>
{{GetGeneratedCodeAttributeSrc()}} {{GetGeneratedCodeAttributeSrc()}}
internal static class {{className}} internal static class {{className}}
{
"""); """);
_emitBlankLineBeforeNextStatement = false; _emitBlankLineBeforeNextStatement = false;
......
...@@ -16,12 +16,12 @@ private void EmitBinder_Extensions_OptionsBuilder() ...@@ -16,12 +16,12 @@ private void EmitBinder_Extensions_OptionsBuilder()
return; return;
} }
EmitRootBindingClassBlockStart(Identifier.GeneratedOptionsBuilderBinder); EmitRootBindingClassStartBlock(Identifier.GeneratedOptionsBuilderBinder);
EmitBindMethods_Extensions_OptionsBuilder(); EmitBindMethods_Extensions_OptionsBuilder();
EmitBindConfigurationMethod(); EmitBindConfigurationMethod();
_writer.WriteBlockEnd(); EmitEndBlock();
} }
private void EmitBindMethods_Extensions_OptionsBuilder() private void EmitBindMethods_Extensions_OptionsBuilder()
...@@ -36,24 +36,24 @@ private void EmitBindMethods_Extensions_OptionsBuilder() ...@@ -36,24 +36,24 @@ private void EmitBindMethods_Extensions_OptionsBuilder()
if (ShouldEmitMethods(MethodsToGen_Extensions_OptionsBuilder.Bind_T)) if (ShouldEmitMethods(MethodsToGen_Extensions_OptionsBuilder.Bind_T))
{ {
EmitMethodBlockStart("Bind", paramList, documentation); EmitMethodStartBlock("Bind", paramList, documentation);
_writer.WriteLine($"return global::{Identifier.GeneratedOptionsBuilderBinder}.Bind({Identifier.optionsBuilder}, {Identifier.configuration}, {Identifier.configureOptions}: null);"); _writer.WriteLine($"return global::{Identifier.GeneratedOptionsBuilderBinder}.Bind({Identifier.optionsBuilder}, {Identifier.configuration}, {Identifier.configureOptions}: null);");
_writer.WriteBlockEnd(); EmitEndBlock();
} }
EmitMethodBlockStart( EmitMethodStartBlock(
"Bind", "Bind",
paramList + $", {FullyQualifiedDisplayString.ActionOfBinderOptions}? {Identifier.configureOptions}", paramList + $", {FullyQualifiedDisplayString.ActionOfBinderOptions}? {Identifier.configureOptions}",
documentation); documentation);
EmitCheckForNullArgument_WithBlankLine(Identifier.optionsBuilder); EmitCheckForNullArgument_WithBlankLine(Identifier.optionsBuilder);
_writer.WriteBlock($$""" _writer.WriteLine($$"""
global::{{Identifier.GeneratedServiceCollectionBinder}}.{{Identifier.Configure}}<{{Identifier.TOptions}}>({{Identifier.optionsBuilder}}.{{Identifier.Services}}, {{Identifier.optionsBuilder}}.Name, {{Identifier.configuration}}, {{Identifier.configureOptions}}); global::{{Identifier.GeneratedServiceCollectionBinder}}.{{Identifier.Configure}}<{{Identifier.TOptions}}>({{Identifier.optionsBuilder}}.{{Identifier.Services}}, {{Identifier.optionsBuilder}}.Name, {{Identifier.configuration}}, {{Identifier.configureOptions}});
return {{Identifier.optionsBuilder}}; return {{Identifier.optionsBuilder}};
"""); """);
_writer.WriteBlockEnd(); EmitEndBlock();
} }
private void EmitBindConfigurationMethod() private void EmitBindConfigurationMethod()
...@@ -66,37 +66,37 @@ private void EmitBindConfigurationMethod() ...@@ -66,37 +66,37 @@ private void EmitBindConfigurationMethod()
const string documentation = $@"/// <summary>Registers the dependency injection container to bind <typeparamref name=""TOptions""/> against the <see cref=""{FullyQualifiedDisplayString.IConfiguration}""/> obtained from the DI service provider.</summary>"; const string documentation = $@"/// <summary>Registers the dependency injection container to bind <typeparamref name=""TOptions""/> against the <see cref=""{FullyQualifiedDisplayString.IConfiguration}""/> obtained from the DI service provider.</summary>";
string paramList = $"string {Identifier.configSectionPath}, {FullyQualifiedDisplayString.ActionOfBinderOptions}? {Identifier.configureOptions} = null"; string paramList = $"string {Identifier.configSectionPath}, {FullyQualifiedDisplayString.ActionOfBinderOptions}? {Identifier.configureOptions} = null";
EmitMethodBlockStart("BindConfiguration", paramList, documentation); EmitMethodStartBlock("BindConfiguration", paramList, documentation);
EmitCheckForNullArgument_WithBlankLine(Identifier.optionsBuilder); EmitCheckForNullArgument_WithBlankLine(Identifier.optionsBuilder);
EmitCheckForNullArgument_WithBlankLine(Identifier.configSectionPath); EmitCheckForNullArgument_WithBlankLine(Identifier.configSectionPath);
_writer.WriteBlockStart($"{Identifier.optionsBuilder}.{Identifier.Configure}<{FullyQualifiedDisplayString.IConfiguration}>(({Identifier.obj}, {Identifier.configuration}) =>"); EmitStartBlock($"{Identifier.optionsBuilder}.{Identifier.Configure}<{FullyQualifiedDisplayString.IConfiguration}>(({Identifier.obj}, {Identifier.configuration}) =>");
_writer.WriteBlock($$""" _writer.WriteLine($$"""
{{FullyQualifiedDisplayString.IConfiguration}} {{Identifier.section}} = string.Equals(string.Empty, {{Identifier.configSectionPath}}, global::System.StringComparison.OrdinalIgnoreCase) ? {{Identifier.configuration}} : {{Identifier.configuration}}.{{Identifier.GetSection}}({{Identifier.configSectionPath}}); {{FullyQualifiedDisplayString.IConfiguration}} {{Identifier.section}} = string.Equals(string.Empty, {{Identifier.configSectionPath}}, global::System.StringComparison.OrdinalIgnoreCase) ? {{Identifier.configuration}} : {{Identifier.configuration}}.{{Identifier.GetSection}}({{Identifier.configSectionPath}});
{{FullyQualifiedDisplayString.CoreBindingHelper}}.{{nameof(MethodsToGen_CoreBindingHelper.BindCoreUntyped)}}({{Identifier.section}}, {{Identifier.obj}}, typeof({{Identifier.TOptions}}), {{Identifier.configureOptions}}); {{FullyQualifiedDisplayString.CoreBindingHelper}}.{{nameof(MethodsToGen_CoreBindingHelper.BindCoreUntyped)}}({{Identifier.section}}, {{Identifier.obj}}, typeof({{Identifier.TOptions}}), {{Identifier.configureOptions}});
"""); """);
_writer.WriteBlockEnd(");"); EmitEndBlock(endBraceTrailingSource: ");");
_writer.WriteBlankLine(); _writer.WriteLine();
_writer.WriteBlock($$""" _writer.WriteLine($$"""
{{FullyQualifiedDisplayString.AddSingleton}}<{{FullyQualifiedDisplayString.IOptionsChangeTokenSource}}<{{Identifier.TOptions}}>, {{FullyQualifiedDisplayString.ConfigurationChangeTokenSource}}<{{Identifier.TOptions}}>>({{Identifier.optionsBuilder}}.{{Identifier.Services}}); {{FullyQualifiedDisplayString.AddSingleton}}<{{FullyQualifiedDisplayString.IOptionsChangeTokenSource}}<{{Identifier.TOptions}}>, {{FullyQualifiedDisplayString.ConfigurationChangeTokenSource}}<{{Identifier.TOptions}}>>({{Identifier.optionsBuilder}}.{{Identifier.Services}});
return {{Identifier.optionsBuilder}}; return {{Identifier.optionsBuilder}};
"""); """);
_writer.WriteBlockEnd(); EmitEndBlock();
} }
private void EmitMethodBlockStart(string methodName, string paramList, string documentation) private void EmitMethodStartBlock(string methodName, string paramList, string documentation)
{ {
paramList = $"this {FullyQualifiedDisplayString.OptionsBuilderOfTOptions} {Identifier.optionsBuilder}, {paramList}"; paramList = $"this {FullyQualifiedDisplayString.OptionsBuilderOfTOptions} {Identifier.optionsBuilder}, {paramList}";
EmitBlankLineIfRequired(); EmitBlankLineIfRequired();
_writer.WriteLine(documentation); _writer.WriteLine(documentation);
_writer.WriteBlockStart($"public static {FullyQualifiedDisplayString.OptionsBuilderOfTOptions} {methodName}<{Identifier.TOptions}>({paramList}) where {Identifier.TOptions} : class"); EmitStartBlock($"public static {FullyQualifiedDisplayString.OptionsBuilderOfTOptions} {methodName}<{Identifier.TOptions}>({paramList}) where {Identifier.TOptions} : class");
} }
} }
} }
......
...@@ -9,14 +9,14 @@ private sealed partial class Emitter ...@@ -9,14 +9,14 @@ private sealed partial class Emitter
{ {
private bool ShouldEmitMethods(MethodsToGen_Extensions_ServiceCollection methods) => (_sourceGenSpec.MethodsToGen_ServiceCollectionExt & methods) != 0; private bool ShouldEmitMethods(MethodsToGen_Extensions_ServiceCollection methods) => (_sourceGenSpec.MethodsToGen_ServiceCollectionExt & methods) != 0;
private void EmitBinder_Extensions_ServiceCollection() private void EmitBinder_Extensions_IServiceCollection()
{ {
if (!ShouldEmitMethods(MethodsToGen_Extensions_ServiceCollection.Any)) if (!ShouldEmitMethods(MethodsToGen_Extensions_ServiceCollection.Any))
{ {
return; return;
} }
EmitRootBindingClassBlockStart(Identifier.GeneratedServiceCollectionBinder); EmitRootBindingClassStartBlock(Identifier.GeneratedServiceCollectionBinder);
const string defaultNameExpr = "string.Empty"; const string defaultNameExpr = "string.Empty";
const string configureMethodString = $"global::{Identifier.GeneratedServiceCollectionBinder}.{Identifier.Configure}"; const string configureMethodString = $"global::{Identifier.GeneratedServiceCollectionBinder}.{Identifier.Configure}";
...@@ -24,56 +24,56 @@ private void EmitBinder_Extensions_ServiceCollection() ...@@ -24,56 +24,56 @@ private void EmitBinder_Extensions_ServiceCollection()
if (ShouldEmitMethods(MethodsToGen_Extensions_ServiceCollection.Configure_T)) if (ShouldEmitMethods(MethodsToGen_Extensions_ServiceCollection.Configure_T))
{ {
EmitBlockStart(configParam); EmitStartMethod(configParam);
_writer.WriteLine($"return {configureMethodString}<{Identifier.TOptions}>({Identifier.services}, {defaultNameExpr}, {Identifier.configuration}, {Identifier.configureOptions}: null);"); _writer.WriteLine($"return {configureMethodString}<{Identifier.TOptions}>({Identifier.services}, {defaultNameExpr}, {Identifier.configuration}, {Identifier.configureOptions}: null);");
_writer.WriteBlockEnd(); EmitEndBlock();
} }
if (ShouldEmitMethods(MethodsToGen_Extensions_ServiceCollection.Configure_T_name)) if (ShouldEmitMethods(MethodsToGen_Extensions_ServiceCollection.Configure_T_name))
{ {
EmitBlockStart( EmitStartMethod(
paramList: $"string? {Identifier.name}, " + configParam); paramList: $"string? {Identifier.name}, " + configParam);
_writer.WriteLine($"return {configureMethodString}<{Identifier.TOptions}>({Identifier.services}, {Identifier.name}, {Identifier.configuration}, {Identifier.configureOptions}: null);"); _writer.WriteLine($"return {configureMethodString}<{Identifier.TOptions}>({Identifier.services}, {Identifier.name}, {Identifier.configuration}, {Identifier.configureOptions}: null);");
_writer.WriteBlockEnd(); EmitEndBlock();
} }
if (ShouldEmitMethods(MethodsToGen_Extensions_ServiceCollection.Configure_T_BinderOptions)) if (ShouldEmitMethods(MethodsToGen_Extensions_ServiceCollection.Configure_T_BinderOptions))
{ {
EmitBlockStart( EmitStartMethod(
paramList: configParam + $", {FullyQualifiedDisplayString.ActionOfBinderOptions}? {Identifier.configureOptions}"); paramList: configParam + $", {FullyQualifiedDisplayString.ActionOfBinderOptions}? {Identifier.configureOptions}");
_writer.WriteLine($"return {configureMethodString}<{Identifier.TOptions}>({Identifier.services}, {defaultNameExpr}, {Identifier.configuration}, {Identifier.configureOptions});"); _writer.WriteLine($"return {configureMethodString}<{Identifier.TOptions}>({Identifier.services}, {defaultNameExpr}, {Identifier.configuration}, {Identifier.configureOptions});");
_writer.WriteBlockEnd(); EmitEndBlock();
} }
// Core Configure method that the other overloads call.
// Like the others, it is public API that could be called directly by users.
// So, it is always generated whenever a Configure overload is called.
string optionsNamespaceName = "global::Microsoft.Extensions.Options"; string optionsNamespaceName = "global::Microsoft.Extensions.Options";
string bindCoreUntypedDisplayString = GetHelperMethodDisplayString(nameof(MethodsToGen_CoreBindingHelper.BindCoreUntyped)); string bindCoreUntypedDisplayString = GetHelperMethodDisplayString(nameof(MethodsToGen_CoreBindingHelper.BindCoreUntyped));
EmitBlockStart(paramList: $"string? {Identifier.name}, " + configParam + $", {FullyQualifiedDisplayString.ActionOfBinderOptions}? {Identifier.configureOptions}"); EmitStartMethod(paramList: $"string? {Identifier.name}, " + configParam + $", {FullyQualifiedDisplayString.ActionOfBinderOptions}? {Identifier.configureOptions}");
EmitCheckForNullArgument_WithBlankLine(Identifier.services); EmitCheckForNullArgument_WithBlankLine(Identifier.services);
EmitCheckForNullArgument_WithBlankLine(Identifier.configuration); EmitCheckForNullArgument_WithBlankLine(Identifier.configuration);
_writer.WriteLine($$"""
_writer.WriteBlock($$"""
global::Microsoft.Extensions.DependencyInjection.OptionsServiceCollectionExtensions.AddOptions({{Identifier.services}}); global::Microsoft.Extensions.DependencyInjection.OptionsServiceCollectionExtensions.AddOptions({{Identifier.services}});
{{FullyQualifiedDisplayString.AddSingleton}}<{{FullyQualifiedDisplayString.IOptionsChangeTokenSource}}<{{Identifier.TOptions}}>>({{Identifier.services}}, new {{FullyQualifiedDisplayString.ConfigurationChangeTokenSource}}<{{Identifier.TOptions}}>({{Identifier.name}}, {{Identifier.configuration}})); {{FullyQualifiedDisplayString.AddSingleton}}<{{FullyQualifiedDisplayString.IOptionsChangeTokenSource}}<{{Identifier.TOptions}}>>({{Identifier.services}}, new {{FullyQualifiedDisplayString.ConfigurationChangeTokenSource}}<{{Identifier.TOptions}}>({{Identifier.name}}, {{Identifier.configuration}}));
return {{FullyQualifiedDisplayString.AddSingleton}}<{{optionsNamespaceName}}.IConfigureOptions<{{Identifier.TOptions}}>>({{Identifier.services}}, new {{optionsNamespaceName}}.ConfigureNamedOptions<{{Identifier.TOptions}}>({{Identifier.name}}, {{Identifier.obj}} => {{bindCoreUntypedDisplayString}}({{Identifier.configuration}}, {{Identifier.obj}}, typeof({{Identifier.TOptions}}), {{Identifier.configureOptions}}))); return {{FullyQualifiedDisplayString.AddSingleton}}<{{optionsNamespaceName}}.IConfigureOptions<{{Identifier.TOptions}}>>({{Identifier.services}}, new {{optionsNamespaceName}}.ConfigureNamedOptions<{{Identifier.TOptions}}>({{Identifier.name}}, {{Identifier.obj}} => {{bindCoreUntypedDisplayString}}({{Identifier.configuration}}, {{Identifier.obj}}, typeof({{Identifier.TOptions}}), {{Identifier.configureOptions}})));
} """);
"""); EmitEndBlock();
_writer.WriteBlockEnd(); EmitEndBlock();
_emitBlankLineBeforeNextStatement = true; _emitBlankLineBeforeNextStatement = true;
} }
private void EmitBlockStart(string paramList) private void EmitStartMethod(string paramList)
{ {
paramList = $"this {FullyQualifiedDisplayString.IServiceCollection} {Identifier.services}, {paramList}"; paramList = $"this {FullyQualifiedDisplayString.IServiceCollection} {Identifier.services}, {paramList}";
EmitBlankLineIfRequired(); EmitBlankLineIfRequired();
_writer.WriteBlock($$""" EmitStartBlock($$"""
/// <summary>Registers a configuration instance which TOptions will bind against.</summary> /// <summary>Registers a configuration instance which TOptions will bind against.</summary>
public static {{FullyQualifiedDisplayString.IServiceCollection}} {{Identifier.Configure}}<{{Identifier.TOptions}}>({{paramList}}) where {{Identifier.TOptions}} : class public static {{FullyQualifiedDisplayString.IServiceCollection}} {{Identifier.Configure}}<{{Identifier.TOptions}}>({{paramList}}) where {{Identifier.TOptions}} : class
{ """);
""");
} }
} }
} }
......
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Diagnostics;
using System.Text;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
internal sealed class SourceWriter
{
private readonly StringBuilder _sb = new();
private static readonly char[] s_newLine = Environment.NewLine.ToCharArray();
private int _indentation;
public void WriteBlockStart(string? declaration = null)
{
if (declaration is not null)
{
WriteLine(declaration);
}
WriteLine("{");
_indentation++;
}
public void WriteBlockEnd(string? extra = null)
{
_indentation--;
Debug.Assert(_indentation > -1);
WriteLine($"}}{extra}");
}
public void WriteLine(string source)
{
_sb.Append(' ', 4 * _indentation);
_sb.AppendLine(source);
}
public void WriteBlock(string source)
{
bool isFinalLine;
ReadOnlySpan<char> remainingText = source.AsSpan();
do
{
ReadOnlySpan<char> line = GetNextLine(ref remainingText, out isFinalLine);
switch (line)
{
case "{":
{
WriteBlockStart();
}
break;
case "}":
{
WriteBlockEnd();
}
break;
default:
{
WriteLine(line);
}
break;
}
} while (!isFinalLine);
}
public void WriteBlankLine() => _sb.AppendLine();
public SourceText ToSourceText()
{
Debug.Assert(_indentation == 0 && _sb.Length > 0);
return SourceText.From(_sb.ToString(), Encoding.UTF8);
}
private static ReadOnlySpan<char> GetNextLine(ref ReadOnlySpan<char> remainingText, out bool isFinalLine)
{
if (remainingText.IsEmpty)
{
isFinalLine = true;
return default;
}
ReadOnlySpan<char> next;
ReadOnlySpan<char> rest;
remainingText = remainingText.Trim();
int lineLength = remainingText.IndexOf(s_newLine);
if (lineLength == -1)
{
lineLength = remainingText.Length;
isFinalLine = true;
rest = default;
}
else
{
rest = remainingText.Slice(lineLength + 1);
isFinalLine = false;
}
next = remainingText.Slice(0, lineLength);
remainingText = rest;
return next;
}
private unsafe void WriteLine(ReadOnlySpan<char> source)
{
_sb.Append(' ', 4 * _indentation);
fixed (char* ptr = source)
{
_sb.Append(ptr, source.Length);
WriteBlankLine();
}
}
}
}
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
<Compile Include="$(CoreLibSharedDir)System\Collections\Generic\ValueListBuilder.cs" Link="Production\ValueListBuilder.cs" /> <Compile Include="$(CoreLibSharedDir)System\Collections\Generic\ValueListBuilder.cs" Link="Production\ValueListBuilder.cs" />
<Compile Include="$(CoreLibSharedDir)System\Collections\Generic\ValueListBuilder.Pop.cs" Link="Production\ValueListBuilder.Pop.cs" /> <Compile Include="$(CoreLibSharedDir)System\Collections\Generic\ValueListBuilder.Pop.cs" Link="Production\ValueListBuilder.Pop.cs" />
<Compile Include="$(CommonPath)\Roslyn\GetBestTypeByMetadataName.cs" Link="Common\Roslyn\GetBestTypeByMetadataName.cs" /> <Compile Include="$(CommonPath)\Roslyn\GetBestTypeByMetadataName.cs" Link="Common\Roslyn\GetBestTypeByMetadataName.cs" />
<Compile Include="$(CommonPath)\SourceGenerators\SourceWriter.cs" Link="Common\SourceGenerators\SourceWriter.cs" />
<Compile Include="ConfigurationBindingGenerator.cs" /> <Compile Include="ConfigurationBindingGenerator.cs" />
<Compile Include="ConfigurationBindingGenerator.Emitter.cs" /> <Compile Include="ConfigurationBindingGenerator.Emitter.cs" />
<Compile Include="ConfigurationBindingGenerator.Parser.cs" /> <Compile Include="ConfigurationBindingGenerator.Parser.cs" />
...@@ -36,7 +37,6 @@ ...@@ -36,7 +37,6 @@
<Compile Include="Helpers\Parser\Diagnostics.cs" /> <Compile Include="Helpers\Parser\Diagnostics.cs" />
<Compile Include="Helpers\Parser\OptionsBuilderConfigurationExtensions.cs" /> <Compile Include="Helpers\Parser\OptionsBuilderConfigurationExtensions.cs" />
<Compile Include="Helpers\Parser\OptionsConfigurationServiceCollectionExtensions.cs" /> <Compile Include="Helpers\Parser\OptionsConfigurationServiceCollectionExtensions.cs" />
<Compile Include="Helpers\SourceWriter.cs" />
<Compile Include="Model\CollectionSpec.cs" /> <Compile Include="Model\CollectionSpec.cs" />
<Compile Include="Model\ConfigurationSectionSpec.cs" /> <Compile Include="Model\ConfigurationSectionSpec.cs" />
<Compile Include="Model\InitializationStrategy.cs" /> <Compile Include="Model\InitializationStrategy.cs" />
......
...@@ -235,6 +235,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -235,6 +235,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true) if (binderOptions?.ErrorOnUnknownConfiguration is true)
{ {
List<string>? temp = null; List<string>? temp = null;
foreach (IConfigurationSection section in configuration.GetChildren()) foreach (IConfigurationSection section in configuration.GetChildren())
{ {
if (!keys.Value.Contains(section.Key)) if (!keys.Value.Contains(section.Key))
...@@ -242,6 +243,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -242,6 +243,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List<string>()).Add($"'{section.Key}'"); (temp ??= new List<string>()).Add($"'{section.Key}'");
} }
} }
if (temp is not null) if (temp is not null)
{ {
throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}"); throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}");
...@@ -273,12 +275,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -273,12 +275,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{ {
return null; return null;
} }
BinderOptions binderOptions = new(); BinderOptions binderOptions = new();
configureOptions(binderOptions); configureOptions(binderOptions);
if (binderOptions.BindNonPublicProperties) if (binderOptions.BindNonPublicProperties)
{ {
throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.");
} }
return binderOptions; return binderOptions;
} }
......
...@@ -126,6 +126,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -126,6 +126,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true) if (binderOptions?.ErrorOnUnknownConfiguration is true)
{ {
List<string>? temp = null; List<string>? temp = null;
foreach (IConfigurationSection section in configuration.GetChildren()) foreach (IConfigurationSection section in configuration.GetChildren())
{ {
if (!keys.Value.Contains(section.Key)) if (!keys.Value.Contains(section.Key))
...@@ -133,6 +134,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -133,6 +134,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List<string>()).Add($"'{section.Key}'"); (temp ??= new List<string>()).Add($"'{section.Key}'");
} }
} }
if (temp is not null) if (temp is not null)
{ {
throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}"); throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}");
...@@ -155,12 +157,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -155,12 +157,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{ {
return null; return null;
} }
BinderOptions binderOptions = new(); BinderOptions binderOptions = new();
configureOptions(binderOptions); configureOptions(binderOptions);
if (binderOptions.BindNonPublicProperties) if (binderOptions.BindNonPublicProperties)
{ {
throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.");
} }
return binderOptions; return binderOptions;
} }
......
...@@ -120,6 +120,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -120,6 +120,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true) if (binderOptions?.ErrorOnUnknownConfiguration is true)
{ {
List<string>? temp = null; List<string>? temp = null;
foreach (IConfigurationSection section in configuration.GetChildren()) foreach (IConfigurationSection section in configuration.GetChildren())
{ {
if (!keys.Value.Contains(section.Key)) if (!keys.Value.Contains(section.Key))
...@@ -127,6 +128,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -127,6 +128,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List<string>()).Add($"'{section.Key}'"); (temp ??= new List<string>()).Add($"'{section.Key}'");
} }
} }
if (temp is not null) if (temp is not null)
{ {
throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}"); throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}");
......
...@@ -120,6 +120,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -120,6 +120,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true) if (binderOptions?.ErrorOnUnknownConfiguration is true)
{ {
List<string>? temp = null; List<string>? temp = null;
foreach (IConfigurationSection section in configuration.GetChildren()) foreach (IConfigurationSection section in configuration.GetChildren())
{ {
if (!keys.Value.Contains(section.Key)) if (!keys.Value.Contains(section.Key))
...@@ -127,6 +128,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -127,6 +128,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List<string>()).Add($"'{section.Key}'"); (temp ??= new List<string>()).Add($"'{section.Key}'");
} }
} }
if (temp is not null) if (temp is not null)
{ {
throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}"); throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}");
...@@ -149,12 +151,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -149,12 +151,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{ {
return null; return null;
} }
BinderOptions binderOptions = new(); BinderOptions binderOptions = new();
configureOptions(binderOptions); configureOptions(binderOptions);
if (binderOptions.BindNonPublicProperties) if (binderOptions.BindNonPublicProperties)
{ {
throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.");
} }
return binderOptions; return binderOptions;
} }
......
...@@ -120,6 +120,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -120,6 +120,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true) if (binderOptions?.ErrorOnUnknownConfiguration is true)
{ {
List<string>? temp = null; List<string>? temp = null;
foreach (IConfigurationSection section in configuration.GetChildren()) foreach (IConfigurationSection section in configuration.GetChildren())
{ {
if (!keys.Value.Contains(section.Key)) if (!keys.Value.Contains(section.Key))
...@@ -127,6 +128,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -127,6 +128,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List<string>()).Add($"'{section.Key}'"); (temp ??= new List<string>()).Add($"'{section.Key}'");
} }
} }
if (temp is not null) if (temp is not null)
{ {
throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}"); throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}");
......
...@@ -173,6 +173,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -173,6 +173,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true) if (binderOptions?.ErrorOnUnknownConfiguration is true)
{ {
List<string>? temp = null; List<string>? temp = null;
foreach (IConfigurationSection section in configuration.GetChildren()) foreach (IConfigurationSection section in configuration.GetChildren())
{ {
if (!keys.Value.Contains(section.Key)) if (!keys.Value.Contains(section.Key))
...@@ -180,6 +181,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -180,6 +181,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List<string>()).Add($"'{section.Key}'"); (temp ??= new List<string>()).Add($"'{section.Key}'");
} }
} }
if (temp is not null) if (temp is not null)
{ {
throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}"); throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}");
...@@ -211,12 +213,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -211,12 +213,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{ {
return null; return null;
} }
BinderOptions binderOptions = new(); BinderOptions binderOptions = new();
configureOptions(binderOptions); configureOptions(binderOptions);
if (binderOptions.BindNonPublicProperties) if (binderOptions.BindNonPublicProperties)
{ {
throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.");
} }
return binderOptions; return binderOptions;
} }
......
...@@ -141,6 +141,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -141,6 +141,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true) if (binderOptions?.ErrorOnUnknownConfiguration is true)
{ {
List<string>? temp = null; List<string>? temp = null;
foreach (IConfigurationSection section in configuration.GetChildren()) foreach (IConfigurationSection section in configuration.GetChildren())
{ {
if (!keys.Value.Contains(section.Key)) if (!keys.Value.Contains(section.Key))
...@@ -148,6 +149,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -148,6 +149,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List<string>()).Add($"'{section.Key}'"); (temp ??= new List<string>()).Add($"'{section.Key}'");
} }
} }
if (temp is not null) if (temp is not null)
{ {
throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}"); throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}");
...@@ -179,12 +181,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -179,12 +181,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{ {
return null; return null;
} }
BinderOptions binderOptions = new(); BinderOptions binderOptions = new();
configureOptions(binderOptions); configureOptions(binderOptions);
if (binderOptions.BindNonPublicProperties) if (binderOptions.BindNonPublicProperties)
{ {
throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.");
} }
return binderOptions; return binderOptions;
} }
......
...@@ -141,6 +141,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -141,6 +141,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true) if (binderOptions?.ErrorOnUnknownConfiguration is true)
{ {
List<string>? temp = null; List<string>? temp = null;
foreach (IConfigurationSection section in configuration.GetChildren()) foreach (IConfigurationSection section in configuration.GetChildren())
{ {
if (!keys.Value.Contains(section.Key)) if (!keys.Value.Contains(section.Key))
...@@ -148,6 +149,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -148,6 +149,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List<string>()).Add($"'{section.Key}'"); (temp ??= new List<string>()).Add($"'{section.Key}'");
} }
} }
if (temp is not null) if (temp is not null)
{ {
throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}"); throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}");
...@@ -179,12 +181,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -179,12 +181,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{ {
return null; return null;
} }
BinderOptions binderOptions = new(); BinderOptions binderOptions = new();
configureOptions(binderOptions); configureOptions(binderOptions);
if (binderOptions.BindNonPublicProperties) if (binderOptions.BindNonPublicProperties)
{ {
throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.");
} }
return binderOptions; return binderOptions;
} }
......
...@@ -69,6 +69,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -69,6 +69,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true) if (binderOptions?.ErrorOnUnknownConfiguration is true)
{ {
List<string>? temp = null; List<string>? temp = null;
foreach (IConfigurationSection section in configuration.GetChildren()) foreach (IConfigurationSection section in configuration.GetChildren())
{ {
if (!keys.Value.Contains(section.Key)) if (!keys.Value.Contains(section.Key))
...@@ -76,6 +77,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -76,6 +77,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List<string>()).Add($"'{section.Key}'"); (temp ??= new List<string>()).Add($"'{section.Key}'");
} }
} }
if (temp is not null) if (temp is not null)
{ {
throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}"); throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}");
...@@ -107,12 +109,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -107,12 +109,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{ {
return null; return null;
} }
BinderOptions binderOptions = new(); BinderOptions binderOptions = new();
configureOptions(binderOptions); configureOptions(binderOptions);
if (binderOptions.BindNonPublicProperties) if (binderOptions.BindNonPublicProperties)
{ {
throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.");
} }
return binderOptions; return binderOptions;
} }
......
...@@ -69,6 +69,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -69,6 +69,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true) if (binderOptions?.ErrorOnUnknownConfiguration is true)
{ {
List<string>? temp = null; List<string>? temp = null;
foreach (IConfigurationSection section in configuration.GetChildren()) foreach (IConfigurationSection section in configuration.GetChildren())
{ {
if (!keys.Value.Contains(section.Key)) if (!keys.Value.Contains(section.Key))
...@@ -76,6 +77,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -76,6 +77,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List<string>()).Add($"'{section.Key}'"); (temp ??= new List<string>()).Add($"'{section.Key}'");
} }
} }
if (temp is not null) if (temp is not null)
{ {
throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}"); throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}");
...@@ -107,12 +109,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -107,12 +109,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{ {
return null; return null;
} }
BinderOptions binderOptions = new(); BinderOptions binderOptions = new();
configureOptions(binderOptions); configureOptions(binderOptions);
if (binderOptions.BindNonPublicProperties) if (binderOptions.BindNonPublicProperties)
{ {
throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.");
} }
return binderOptions; return binderOptions;
} }
......
...@@ -116,6 +116,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -116,6 +116,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true) if (binderOptions?.ErrorOnUnknownConfiguration is true)
{ {
List<string>? temp = null; List<string>? temp = null;
foreach (IConfigurationSection section in configuration.GetChildren()) foreach (IConfigurationSection section in configuration.GetChildren())
{ {
if (!keys.Value.Contains(section.Key)) if (!keys.Value.Contains(section.Key))
...@@ -123,6 +124,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -123,6 +124,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List<string>()).Add($"'{section.Key}'"); (temp ??= new List<string>()).Add($"'{section.Key}'");
} }
} }
if (temp is not null) if (temp is not null)
{ {
throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}"); throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}");
...@@ -154,12 +156,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -154,12 +156,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{ {
return null; return null;
} }
BinderOptions binderOptions = new(); BinderOptions binderOptions = new();
configureOptions(binderOptions); configureOptions(binderOptions);
if (binderOptions.BindNonPublicProperties) if (binderOptions.BindNonPublicProperties)
{ {
throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.");
} }
return binderOptions; return binderOptions;
} }
......
...@@ -134,6 +134,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -134,6 +134,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true) if (binderOptions?.ErrorOnUnknownConfiguration is true)
{ {
List<string>? temp = null; List<string>? temp = null;
foreach (IConfigurationSection section in configuration.GetChildren()) foreach (IConfigurationSection section in configuration.GetChildren())
{ {
if (!keys.Value.Contains(section.Key)) if (!keys.Value.Contains(section.Key))
...@@ -141,6 +142,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -141,6 +142,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List<string>()).Add($"'{section.Key}'"); (temp ??= new List<string>()).Add($"'{section.Key}'");
} }
} }
if (temp is not null) if (temp is not null)
{ {
throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}"); throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}");
...@@ -172,12 +174,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -172,12 +174,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{ {
return null; return null;
} }
BinderOptions binderOptions = new(); BinderOptions binderOptions = new();
configureOptions(binderOptions); configureOptions(binderOptions);
if (binderOptions.BindNonPublicProperties) if (binderOptions.BindNonPublicProperties)
{ {
throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.");
} }
return binderOptions; return binderOptions;
} }
......
...@@ -128,6 +128,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -128,6 +128,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true) if (binderOptions?.ErrorOnUnknownConfiguration is true)
{ {
List<string>? temp = null; List<string>? temp = null;
foreach (IConfigurationSection section in configuration.GetChildren()) foreach (IConfigurationSection section in configuration.GetChildren())
{ {
if (!keys.Value.Contains(section.Key)) if (!keys.Value.Contains(section.Key))
...@@ -135,6 +136,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -135,6 +136,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List<string>()).Add($"'{section.Key}'"); (temp ??= new List<string>()).Add($"'{section.Key}'");
} }
} }
if (temp is not null) if (temp is not null)
{ {
throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}"); throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}");
...@@ -166,12 +168,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -166,12 +168,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{ {
return null; return null;
} }
BinderOptions binderOptions = new(); BinderOptions binderOptions = new();
configureOptions(binderOptions); configureOptions(binderOptions);
if (binderOptions.BindNonPublicProperties) if (binderOptions.BindNonPublicProperties)
{ {
throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.");
} }
return binderOptions; return binderOptions;
} }
......
...@@ -174,6 +174,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -174,6 +174,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true) if (binderOptions?.ErrorOnUnknownConfiguration is true)
{ {
List<string>? temp = null; List<string>? temp = null;
foreach (IConfigurationSection section in configuration.GetChildren()) foreach (IConfigurationSection section in configuration.GetChildren())
{ {
if (!keys.Value.Contains(section.Key)) if (!keys.Value.Contains(section.Key))
...@@ -181,6 +182,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -181,6 +182,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List<string>()).Add($"'{section.Key}'"); (temp ??= new List<string>()).Add($"'{section.Key}'");
} }
} }
if (temp is not null) if (temp is not null)
{ {
throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}"); throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}");
......
...@@ -179,6 +179,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -179,6 +179,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true) if (binderOptions?.ErrorOnUnknownConfiguration is true)
{ {
List<string>? temp = null; List<string>? temp = null;
foreach (IConfigurationSection section in configuration.GetChildren()) foreach (IConfigurationSection section in configuration.GetChildren())
{ {
if (!keys.Value.Contains(section.Key)) if (!keys.Value.Contains(section.Key))
...@@ -186,6 +187,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -186,6 +187,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List<string>()).Add($"'{section.Key}'"); (temp ??= new List<string>()).Add($"'{section.Key}'");
} }
} }
if (temp is not null) if (temp is not null)
{ {
throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}"); throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}");
...@@ -217,12 +219,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -217,12 +219,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{ {
return null; return null;
} }
BinderOptions binderOptions = new(); BinderOptions binderOptions = new();
configureOptions(binderOptions); configureOptions(binderOptions);
if (binderOptions.BindNonPublicProperties) if (binderOptions.BindNonPublicProperties)
{ {
throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.");
} }
return binderOptions; return binderOptions;
} }
......
...@@ -179,6 +179,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -179,6 +179,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true) if (binderOptions?.ErrorOnUnknownConfiguration is true)
{ {
List<string>? temp = null; List<string>? temp = null;
foreach (IConfigurationSection section in configuration.GetChildren()) foreach (IConfigurationSection section in configuration.GetChildren())
{ {
if (!keys.Value.Contains(section.Key)) if (!keys.Value.Contains(section.Key))
...@@ -186,6 +187,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -186,6 +187,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List<string>()).Add($"'{section.Key}'"); (temp ??= new List<string>()).Add($"'{section.Key}'");
} }
} }
if (temp is not null) if (temp is not null)
{ {
throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}"); throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}");
...@@ -217,12 +219,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -217,12 +219,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{ {
return null; return null;
} }
BinderOptions binderOptions = new(); BinderOptions binderOptions = new();
configureOptions(binderOptions); configureOptions(binderOptions);
if (binderOptions.BindNonPublicProperties) if (binderOptions.BindNonPublicProperties)
{ {
throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.");
} }
return binderOptions; return binderOptions;
} }
......
...@@ -179,6 +179,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -179,6 +179,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true) if (binderOptions?.ErrorOnUnknownConfiguration is true)
{ {
List<string>? temp = null; List<string>? temp = null;
foreach (IConfigurationSection section in configuration.GetChildren()) foreach (IConfigurationSection section in configuration.GetChildren())
{ {
if (!keys.Value.Contains(section.Key)) if (!keys.Value.Contains(section.Key))
...@@ -186,6 +187,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -186,6 +187,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List<string>()).Add($"'{section.Key}'"); (temp ??= new List<string>()).Add($"'{section.Key}'");
} }
} }
if (temp is not null) if (temp is not null)
{ {
throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}"); throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}");
...@@ -217,12 +219,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -217,12 +219,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{ {
return null; return null;
} }
BinderOptions binderOptions = new(); BinderOptions binderOptions = new();
configureOptions(binderOptions); configureOptions(binderOptions);
if (binderOptions.BindNonPublicProperties) if (binderOptions.BindNonPublicProperties)
{ {
throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.");
} }
return binderOptions; return binderOptions;
} }
......
...@@ -173,6 +173,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -173,6 +173,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true) if (binderOptions?.ErrorOnUnknownConfiguration is true)
{ {
List<string>? temp = null; List<string>? temp = null;
foreach (IConfigurationSection section in configuration.GetChildren()) foreach (IConfigurationSection section in configuration.GetChildren())
{ {
if (!keys.Value.Contains(section.Key)) if (!keys.Value.Contains(section.Key))
...@@ -180,6 +181,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -180,6 +181,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List<string>()).Add($"'{section.Key}'"); (temp ??= new List<string>()).Add($"'{section.Key}'");
} }
} }
if (temp is not null) if (temp is not null)
{ {
throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}"); throw new InvalidOperationException($"'ErrorOnUnknownConfiguration' was set on the provided BinderOptions, but the following properties were not found on the instance of {type}: {string.Join(", ", temp)}");
...@@ -211,12 +213,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration ...@@ -211,12 +213,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{ {
return null; return null;
} }
BinderOptions binderOptions = new(); BinderOptions binderOptions = new();
configureOptions(binderOptions); configureOptions(binderOptions);
if (binderOptions.BindNonPublicProperties) if (binderOptions.BindNonPublicProperties)
{ {
throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'."); throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.");
} }
return binderOptions; return binderOptions;
} }
......
...@@ -257,8 +257,7 @@ public class MyClass2 { } ...@@ -257,8 +257,7 @@ public class MyClass2 { }
.Split(Environment.NewLine); .Split(Environment.NewLine);
var (d, r) = await RunGenerator(testSourceCode, languageVersion); var (d, r) = await RunGenerator(testSourceCode, languageVersion);
bool success = RoslynTestUtils.CompareLines(expectedLines, r[0].SourceText, bool success = RoslynTestUtils.CompareLines(expectedLines, r[0].SourceText, out string errorMessage);
out string errorMessage);
#if !SKIP_BASELINES #if !SKIP_BASELINES
Assert.Single(r); Assert.Single(r);
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Text; using Microsoft.CodeAnalysis.Text;
using SourceGenerators;
namespace System.Text.Json.SourceGeneration namespace System.Text.Json.SourceGeneration
{ {
......
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
<Compile Include="$(CoreLibSharedDir)System\Runtime\CompilerServices\IsExternalInit.cs" Link="Common\System\Runtime\CompilerServices\IsExternalInit.cs" /> <Compile Include="$(CoreLibSharedDir)System\Runtime\CompilerServices\IsExternalInit.cs" Link="Common\System\Runtime\CompilerServices\IsExternalInit.cs" />
<Compile Include="$(CoreLibSharedDir)System\Runtime\CompilerServices\CompilerFeatureRequiredAttribute.cs" Link="Common\System\Runtime\CompilerServices\CompilerFeatureRequiredAttribute.cs" /> <Compile Include="$(CoreLibSharedDir)System\Runtime\CompilerServices\CompilerFeatureRequiredAttribute.cs" Link="Common\System\Runtime\CompilerServices\CompilerFeatureRequiredAttribute.cs" />
<Compile Include="$(CoreLibSharedDir)System\Runtime\CompilerServices\RequiredMemberAttribute.cs" Link="Common\System\Runtime\CompilerServices\RequiredMemberAttribute.cs" /> <Compile Include="$(CoreLibSharedDir)System\Runtime\CompilerServices\RequiredMemberAttribute.cs" Link="Common\System\Runtime\CompilerServices\RequiredMemberAttribute.cs" />
<Compile Include="$(CommonPath)\Roslyn\GetBestTypeByMetadataName.cs" Link="Common\Roslyn\GetBestTypeByMetadataName.cs" />
<Compile Include="$(CommonPath)\SourceGenerators\SourceWriter.cs" Link="Common\SourceGenerators\SourceWriter.cs" />
<Compile Include="..\Common\JsonCamelCaseNamingPolicy.cs" Link="Common\System\Text\Json\JsonCamelCaseNamingPolicy.cs" /> <Compile Include="..\Common\JsonCamelCaseNamingPolicy.cs" Link="Common\System\Text\Json\JsonCamelCaseNamingPolicy.cs" />
<Compile Include="..\Common\JsonNamingPolicy.cs" Link="Common\System\Text\Json\JsonNamingPolicy.cs" /> <Compile Include="..\Common\JsonNamingPolicy.cs" Link="Common\System\Text\Json\JsonNamingPolicy.cs" />
<Compile Include="..\Common\JsonAttribute.cs" Link="Common\System\Text\Json\Serialization\JsonAttribute.cs" /> <Compile Include="..\Common\JsonAttribute.cs" Link="Common\System\Text\Json\Serialization\JsonAttribute.cs" />
...@@ -50,13 +52,11 @@ ...@@ -50,13 +52,11 @@
<Compile Include="..\Common\JsonUnknownTypeHandling.cs" Link="Common\System\Text\Json\Serialization\JsonUnknownTypeHandling.cs" /> <Compile Include="..\Common\JsonUnknownTypeHandling.cs" Link="Common\System\Text\Json\Serialization\JsonUnknownTypeHandling.cs" />
<Compile Include="..\Common\JsonUnmappedMemberHandling.cs" Link="Common\System\Text\Json\Serialization\JsonUnmappedMemberHandling.cs" /> <Compile Include="..\Common\JsonUnmappedMemberHandling.cs" Link="Common\System\Text\Json\Serialization\JsonUnmappedMemberHandling.cs" />
<Compile Include="..\Common\ThrowHelper.cs" Link="Common\System\Text\Json\ThrowHelper.cs" /> <Compile Include="..\Common\ThrowHelper.cs" Link="Common\System\Text\Json\ThrowHelper.cs" />
<Compile Include="$(CommonPath)\Roslyn\GetBestTypeByMetadataName.cs" Link="Common\Roslyn\GetBestTypeByMetadataName.cs" />
<Compile Include="Helpers\DiagnosticInfo.cs" /> <Compile Include="Helpers\DiagnosticInfo.cs" />
<Compile Include="Helpers\SourceGeneratorHelpers.cs" /> <Compile Include="Helpers\SourceGeneratorHelpers.cs" />
<Compile Include="Helpers\ImmutableEquatableArray.cs" /> <Compile Include="Helpers\ImmutableEquatableArray.cs" />
<Compile Include="Helpers\KnownTypeSymbols.cs" /> <Compile Include="Helpers\KnownTypeSymbols.cs" />
<Compile Include="Helpers\RoslynExtensions.cs" /> <Compile Include="Helpers\RoslynExtensions.cs" />
<Compile Include="Helpers\SourceWriter.cs" />
<Compile Include="JsonConstants.cs" /> <Compile Include="JsonConstants.cs" />
<Compile Include="JsonSourceGenerator.DiagnosticDescriptors.cs" /> <Compile Include="JsonSourceGenerator.DiagnosticDescriptors.cs" />
<Compile Include="JsonSourceGenerator.Emitter.cs" /> <Compile Include="JsonSourceGenerator.Emitter.cs" />
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册