diff --git a/src/libraries/System.Text.Json/gen/Helpers/SourceWriter.cs b/src/libraries/Common/src/SourceGenerators/SourceWriter.cs
similarity index 79%
rename from src/libraries/System.Text.Json/gen/Helpers/SourceWriter.cs
rename to src/libraries/Common/src/SourceGenerators/SourceWriter.cs
index 8bada81593a64..0cc443d86fc3f 100644
--- a/src/libraries/System.Text.Json/gen/Helpers/SourceWriter.cs
+++ b/src/libraries/Common/src/SourceGenerators/SourceWriter.cs
@@ -1,42 +1,21 @@
// 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.Text;
+using System;
+using System.Text;
using System.Diagnostics;
+using Microsoft.CodeAnalysis.Text;
-namespace System.Text.Json.SourceGeneration
+namespace SourceGenerators
{
internal sealed class SourceWriter
{
+ private const char IndentationChar = ' ';
+ private const int CharsPerIndentation = 4;
+
private readonly StringBuilder _sb = new();
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
{
get => _indentation;
@@ -88,6 +67,12 @@ public SourceText ToSourceText()
return SourceText.From(_sb.ToString(), Encoding.UTF8);
}
+ public void Reset()
+ {
+ _sb.Clear();
+ _indentation = 0;
+ }
+
private void AddIndentation()
=> _sb.Append(IndentationChar, CharsPerIndentation * _indentation);
diff --git a/src/libraries/Common/tests/Common.Tests.csproj b/src/libraries/Common/tests/Common.Tests.csproj
index b7e40f2e79890..710ac02810174 100644
--- a/src/libraries/Common/tests/Common.Tests.csproj
+++ b/src/libraries/Common/tests/Common.Tests.csproj
@@ -18,6 +18,8 @@
Link="Common\Interop\Linux\Interop.ProcFsStat.TryReadStatusFile.cs" />
+
+
@@ -155,6 +158,9 @@
+
+
+
diff --git a/src/libraries/Common/tests/Tests/SourceGenerators/SourceWriterTests.cs b/src/libraries/Common/tests/Tests/SourceGenerators/SourceWriterTests.cs
new file mode 100644
index 0000000000000..ab0e53b07d526
--- /dev/null
+++ b/src/libraries/Common/tests/Tests/SourceGenerators/SourceWriterTests.cs
@@ -0,0 +1,32 @@
+// 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>(services, new global::Microsoft.Extensions.Options.ConfigurationChangeTokenSource(name, configuration));\r\n return global::Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton>(services, new global::Microsoft.Extensions.Options.ConfigureNamedOptions(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();
+ }
+ }
+ }
+}
diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Emitter.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Emitter.cs
index f24a43c022ae4..fcfeece70f7b7 100644
--- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Emitter.cs
+++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Emitter.cs
@@ -5,6 +5,7 @@
using System.Diagnostics;
using System.Text.RegularExpressions;
using Microsoft.CodeAnalysis;
+using SourceGenerators;
namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
@@ -36,17 +37,17 @@ public void Emit()
return;
}
- _writer.WriteBlock("""
+ _writer.WriteLine("""
//
#nullable enable
#pragma warning disable CS0612, CS0618 // Suppress warnings about [Obsolete] member usage in generated code.
""");
- _writer.WriteBlankLine();
+ _writer.WriteLine();
_useFullyQualifiedNames = true;
- EmitBinder_ConfigurationBinder();
+ EmitBinder_Extensions_IConfiguration();
EmitBinder_Extensions_OptionsBuilder();
- EmitBinder_Extensions_ServiceCollection();
+ EmitBinder_Extensions_IServiceCollection();
_useFullyQualifiedNames = false;
Emit_CoreBindingHelper();
@@ -131,14 +132,16 @@ private void EmitBindLogicFromString(
if (!checkForNullSectionValue)
{
- writeOnSuccess?.Invoke(parsedValueExpr);
+ InvokeWriteOnSuccess();
}
else
{
- _writer.WriteBlockStart($"if ({sectionValueExpr} is string {nonNull_StringValue_Identifier})");
- writeOnSuccess?.Invoke(parsedValueExpr);
- _writer.WriteBlockEnd();
+ EmitStartBlock($"if ({sectionValueExpr} is string {nonNull_StringValue_Identifier})");
+ InvokeWriteOnSuccess();
+ EmitEndBlock();
}
+
+ void InvokeWriteOnSuccess() => writeOnSuccess?.Invoke(parsedValueExpr);
}
private bool EmitObjectInit(TypeSpec type, string memberAccessExpr, InitializationKind initKind, string configArgExpr)
@@ -222,7 +225,7 @@ private void EmitCastToIConfigurationSection()
exceptionTypeDisplayString = nameof(InvalidOperationException);
}
- _writer.WriteBlock($$"""
+ _writer.WriteLine($$"""
if ({{Identifier.configuration}} is not {{sectionTypeDisplayString}} {{Identifier.section}})
{
throw new {{exceptionTypeDisplayString}}();
@@ -235,13 +238,13 @@ private void EmitIConfigurationHasValueOrChildrenCheck(bool voidReturn)
string returnPostfix = voidReturn ? string.Empty : " null";
string methodDisplayString = GetHelperMethodDisplayString(Identifier.HasValueOrChildren);
- _writer.WriteBlock($$"""
+ _writer.WriteLine($$"""
if (!{{methodDisplayString}}({{Identifier.configuration}}))
{
return{{returnPostfix}};
}
""");
- _writer.WriteBlankLine();
+ _writer.WriteLine();
}
}
}
diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/ConfigurationBinder.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/ConfigurationBinder.cs
index d71e414af19dc..c10e607df75d0 100644
--- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/ConfigurationBinder.cs
+++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/ConfigurationBinder.cs
@@ -14,7 +14,7 @@ private sealed partial class Emitter
{
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 &&
!_sourceGenSpec.TypesForGen_ConfigurationBinder_BindMethods.Keys.Any(overload => (overload & MethodsToGen_ConfigurationBinder.Bind) is 0));
@@ -25,13 +25,13 @@ private void EmitBinder_ConfigurationBinder()
}
_emitBlankLineBeforeNextStatement = false;
- EmitRootBindingClassBlockStart(Identifier.GeneratedConfigurationBinder);
+ EmitRootBindingClassStartBlock(Identifier.GeneratedConfigurationBinder);
EmitGetMethods();
EmitGetValueMethods();
EmitBindMethods_ConfigurationBinder();
- _writer.WriteBlockEnd();
+ EmitEndBlock();
_emitBlankLineBeforeNextStatement = true;
}
diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/CoreBindingHelper.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/CoreBindingHelper.cs
index dd13ee8e2a358..08015d0abc59f 100644
--- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/CoreBindingHelper.cs
+++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/CoreBindingHelper.cs
@@ -19,19 +19,18 @@ private sealed partial class Emitter
private void Emit_CoreBindingHelper()
{
Debug.Assert(_emitBlankLineBeforeNextStatement);
- _writer.WriteBlankLine();
+ _writer.WriteLine();
_emitBlankLineBeforeNextStatement = false;
- _writer.WriteBlockStart($"namespace {ProjectName}");
+ EmitStartBlock($"namespace {ProjectName}");
EmitHelperUsingStatements();
- _writer.WriteBlankLine();
+ _writer.WriteLine();
- _writer.WriteBlock($$"""
+ EmitStartBlock($$"""
/// Provide core binding logic.
{{GetGeneratedCodeAttributeSrc()}}
file static class {{Identifier.CoreBindingHelper}}
- {
""");
EmitConfigurationKeyCaches();
@@ -42,8 +41,8 @@ file static class {{Identifier.CoreBindingHelper}}
EmitInitializeMethods();
EmitHelperMethods();
- _writer.WriteBlockEnd(); // End helper class.
- _writer.WriteBlockEnd(); // End namespace.
+ EmitEndBlock(); // End helper class.
+ EmitEndBlock(); // End namespace.
}
private void EmitHelperUsingStatements()
@@ -88,12 +87,12 @@ private void EmitGetCoreMethod()
}
EmitBlankLineIfRequired();
- _writer.WriteBlockStart($"public static object? {nameof(MethodsToGen_CoreBindingHelper.GetCore)}(this {Identifier.IConfiguration} {Identifier.configuration}, Type {Identifier.type}, Action<{Identifier.BinderOptions}>? {Identifier.configureOptions})");
+ EmitStartBlock($"public static object? {nameof(MethodsToGen_CoreBindingHelper.GetCore)}(this {Identifier.IConfiguration} {Identifier.configuration}, Type {Identifier.type}, Action<{Identifier.BinderOptions}>? {Identifier.configureOptions})");
EmitCheckForNullArgument_WithBlankLine(Identifier.configuration);
_writer.WriteLine($"{Identifier.BinderOptions}? {Identifier.binderOptions} = {Identifier.GetBinderOptions}({Identifier.configureOptions});");
- _writer.WriteBlankLine();
+ _writer.WriteLine();
EmitIConfigurationHasValueOrChildrenCheck(voidReturn: false);
@@ -101,7 +100,7 @@ private void EmitGetCoreMethod()
{
TypeSpecKind kind = type.SpecKind;
- _writer.WriteBlockStart($"if (type == typeof({type.MinimalDisplayString}))");
+ EmitStartBlock($"if (type == typeof({type.MinimalDisplayString}))");
if (type is ParsableFromStringSpec stringParsableType)
{
@@ -120,12 +119,12 @@ private void EmitGetCoreMethod()
_writer.WriteLine($"return {Identifier.obj};");
}
- _writer.WriteBlockEnd();
- _writer.WriteBlankLine();
+ EmitEndBlock();
+ _writer.WriteLine();
}
Emit_NotSupportedException_TypeNotDetectedAsInput();
- _writer.WriteBlockEnd();
+ EmitEndBlock();
_emitBlankLineBeforeNextStatement = true;
}
@@ -137,24 +136,24 @@ private void EmitGetValueCoreMethod()
}
EmitBlankLineIfRequired();
- _writer.WriteBlockStart($"public static object? {nameof(MethodsToGen_CoreBindingHelper.GetValueCore)}(this {Identifier.IConfiguration} {Identifier.configuration}, Type {Identifier.type}, string {Identifier.key})");
+ EmitStartBlock($"public static object? {nameof(MethodsToGen_CoreBindingHelper.GetValueCore)}(this {Identifier.IConfiguration} {Identifier.configuration}, Type {Identifier.type}, string {Identifier.key})");
EmitCheckForNullArgument_WithBlankLine(Identifier.configuration);
_writer.WriteLine($@"{Identifier.IConfigurationSection} {Identifier.section} = {GetSectionFromConfigurationExpression(Identifier.key, addQuotes: false)};");
- _writer.WriteBlankLine();
+ _writer.WriteLine();
- _writer.WriteBlock($$"""
+ _writer.WriteLine($$"""
if ({{Expression.sectionValue}} is not string {{Identifier.value}})
{
return null;
}
""");
- _writer.WriteBlankLine();
+ _writer.WriteLine();
foreach (TypeSpec type in targetTypes)
{
- _writer.WriteBlockStart($"if ({Identifier.type} == typeof({type.MinimalDisplayString}))");
+ EmitStartBlock($"if ({Identifier.type} == typeof({type.MinimalDisplayString}))");
EmitBindLogicFromString(
(ParsableFromStringSpec)type.EffectiveType,
@@ -164,12 +163,12 @@ private void EmitGetValueCoreMethod()
checkForNullSectionValue: false,
useIncrementalStringValueIdentifier: false);
- _writer.WriteBlockEnd();
- _writer.WriteBlankLine();
+ EmitEndBlock();
+ _writer.WriteLine();
}
_writer.WriteLine("return null;");
- _writer.WriteBlockEnd();
+ EmitEndBlock();
_emitBlankLineBeforeNextStatement = true;
}
@@ -182,18 +181,18 @@ private void EmitBindCoreUntypedMethod()
EmitBlankLineIfRequired();
- _writer.WriteBlockStart($"public static void {nameof(MethodsToGen_CoreBindingHelper.BindCoreUntyped)}(this {Identifier.IConfiguration} {Identifier.configuration}, object {Identifier.obj}, Type {Identifier.type}, {MinimalDisplayString.NullableActionOfBinderOptions} {Identifier.configureOptions})");
+ EmitStartBlock($"public static void {nameof(MethodsToGen_CoreBindingHelper.BindCoreUntyped)}(this {Identifier.IConfiguration} {Identifier.configuration}, object {Identifier.obj}, Type {Identifier.type}, {MinimalDisplayString.NullableActionOfBinderOptions} {Identifier.configureOptions})");
EmitCheckForNullArgument_WithBlankLine(Identifier.configuration);
_writer.WriteLine($"{Identifier.BinderOptions}? {Identifier.binderOptions} = {Identifier.GetBinderOptions}({Identifier.configureOptions});");
- _writer.WriteBlankLine();
+ _writer.WriteLine();
EmitIConfigurationHasValueOrChildrenCheck(voidReturn: true);
foreach (TypeSpec type in targetTypes)
{
- _writer.WriteBlockStart($"if (type == typeof({type.MinimalDisplayString}))");
+ EmitStartBlock($"if (type == typeof({type.MinimalDisplayString}))");
TypeSpec effectiveType = type.EffectiveType;
if (!EmitInitException(effectiveType))
@@ -203,12 +202,12 @@ private void EmitBindCoreUntypedMethod()
_writer.WriteLine($"return;");
}
- _writer.WriteBlockEnd();
- _writer.WriteBlankLine();
+ EmitEndBlock();
+ _writer.WriteLine();
}
Emit_NotSupportedException_TypeNotDetectedAsInput();
- _writer.WriteBlockEnd();
+ EmitEndBlock();
_emitBlankLineBeforeNextStatement = true;
}
@@ -232,7 +231,7 @@ private void EmitBindCoreMethod(TypeSpec type)
Debug.Assert(type.CanInitialize);
string objParameterExpression = $"ref {type.MinimalDisplayString} {Identifier.obj}";
- _writer.WriteBlockStart(@$"public static void {nameof(MethodsToGen_CoreBindingHelper.BindCore)}({Identifier.IConfiguration} {Identifier.configuration}, {objParameterExpression}, {Identifier.BinderOptions}? {Identifier.binderOptions})");
+ EmitStartBlock(@$"public static void {nameof(MethodsToGen_CoreBindingHelper.BindCore)}({Identifier.IConfiguration} {Identifier.configuration}, {objParameterExpression}, {Identifier.BinderOptions}? {Identifier.binderOptions})");
EmitCheckForNullArgument_WithBlankLine_IfRequired(type.IsValueType);
@@ -258,7 +257,7 @@ private void EmitBindCoreMethod(TypeSpec type)
EmitBindCoreImplForObject((ObjectSpec)effectiveType);
}
- _writer.WriteBlockEnd();
+ EmitEndBlock();
}
private void EmitInitializeMethods()
@@ -283,7 +282,7 @@ private void EmitInitializeMethod(ObjectSpec type)
List ctorArgList = new();
string displayString = type.MinimalDisplayString;
- _writer.WriteBlockStart($"public static {type.MinimalDisplayString} {GetInitalizeMethodDisplayString(type)}({Identifier.IConfiguration} {Identifier.configuration}, {Identifier.BinderOptions}? {Identifier.binderOptions})");
+ EmitStartBlock($"public static {type.MinimalDisplayString} {GetInitalizeMethodDisplayString(type)}({Identifier.IConfiguration} {Identifier.configuration}, {Identifier.BinderOptions}? {Identifier.binderOptions})");
_emitBlankLineBeforeNextStatement = false;
foreach (ParameterSpec parameter in ctorParams)
@@ -317,17 +316,17 @@ private void EmitInitializeMethod(ObjectSpec type)
}
else
{
- _writer.WriteBlockStart(returnExpression);
+ EmitStartBlock(returnExpression);
foreach (PropertySpec property in initOnlyProps)
{
string propertyName = property.Name;
_writer.WriteLine($@"{propertyName} = {propertyName},");
}
- _writer.WriteBlockEnd(";");
+ EmitEndBlock(endBraceTrailingSource: ";");
}
// End method.
- _writer.WriteBlockEnd();
+ EmitEndBlock();
_emitBlankLineBeforeNextStatement = true;
void EmitBindImplForMember(MemberSpec member)
@@ -346,7 +345,7 @@ void EmitBindImplForMember(MemberSpec member)
{
string condition = $@" if ({Identifier.configuration}[""{member.ConfigurationKeyName}""] is not {memberType.MinimalDisplayString} {member.Name})";
EmitThrowBlock(condition);
- _writer.WriteBlankLine();
+ _writer.WriteLine();
return;
}
}
@@ -386,11 +385,11 @@ void EmitBindImplForMember(MemberSpec member)
EmitThrowBlock(condition: "else");
}
- _writer.WriteBlankLine();
+ _writer.WriteLine();
}
void EmitThrowBlock(string condition) =>
- _writer.WriteBlock($$"""
+ _writer.WriteLine($$"""
{{condition}}
{
throw new {{GetInvalidOperationDisplayName()}}("{{string.Format(ExceptionMessages.ParameterHasNoMatchingConfig, type.Name, member.Name)}}");
@@ -398,7 +397,6 @@ void EmitThrowBlock(string condition) =>
""");
}
}
-
private void EmitHelperMethods()
{
if (ShouldEmitMethods(MethodsToGen_CoreBindingHelper.BindCore))
@@ -408,15 +406,15 @@ private void EmitHelperMethods()
if (ShouldEmitMethods(MethodsToGen_CoreBindingHelper.BindCoreUntyped | MethodsToGen_CoreBindingHelper.GetCore))
{
- _writer.WriteBlankLine();
+ _writer.WriteLine();
EmitHasValueOrChildrenMethod();
- _writer.WriteBlankLine();
+ _writer.WriteLine();
EmitAsConfigWithChildrenMethod();
_emitBlankLineBeforeNextStatement = true;
}
else if (ShouldEmitMethods(MethodsToGen_CoreBindingHelper.AsConfigWithChildren))
{
- _writer.WriteBlankLine();
+ _writer.WriteLine();
EmitAsConfigWithChildrenMethod();
_emitBlankLineBeforeNextStatement = true;
}
@@ -425,7 +423,7 @@ private void EmitHelperMethods()
MethodsToGen_CoreBindingHelper.BindCoreUntyped | MethodsToGen_CoreBindingHelper.GetCore) ||
ShouldEmitMethods(MethodsToGen_ConfigurationBinder.Bind_instance_BinderOptions))
{
- _writer.WriteBlankLine();
+ _writer.WriteLine();
EmitGetBinderOptionsHelper();
_emitBlankLineBeforeNextStatement = true;
}
@@ -443,7 +441,7 @@ private void EmitValidateConfigurationKeysMethod()
string exceptionMessage = string.Format(ExceptionMessages.MissingConfig, Identifier.ErrorOnUnknownConfiguration, Identifier.BinderOptions, $"{{{Identifier.type}}}", $@"{{string.Join("", "", {Identifier.temp})}}");
EmitBlankLineIfRequired();
- _writer.WriteBlock($$"""
+ _writer.WriteLine($$"""
/// If required by the binder options, validates that there are no unknown keys in the input configuration object.
public static void {{Identifier.ValidateConfigurationKeys}}(Type {{Identifier.type}}, {{MinimalDisplayString.LazyHashSetOfString}} {{keysIdentifier}}, {{Identifier.IConfiguration}} {{Identifier.configuration}}, {{Identifier.BinderOptions}}? {{Identifier.binderOptions}})
{
@@ -470,7 +468,7 @@ private void EmitValidateConfigurationKeysMethod()
private void EmitHasValueOrChildrenMethod()
{
- _writer.WriteBlock($$"""
+ _writer.WriteLine($$"""
public static bool {{Identifier.HasValueOrChildren}}({{Identifier.IConfiguration}} {{Identifier.configuration}})
{
if (({{Identifier.configuration}} as {{Identifier.IConfigurationSection}})?.{{Identifier.Value}} is not null)
@@ -484,7 +482,7 @@ private void EmitHasValueOrChildrenMethod()
private void EmitAsConfigWithChildrenMethod()
{
- _writer.WriteBlock($$"""
+ _writer.WriteLine($$"""
public static {{Identifier.IConfiguration}}? {{Identifier.AsConfigWithChildren}}({{Identifier.IConfiguration}} {{Identifier.configuration}})
{
foreach ({{Identifier.IConfigurationSection}} _ in {{Identifier.configuration}}.{{Identifier.GetChildren}}())
@@ -498,7 +496,7 @@ private void EmitAsConfigWithChildrenMethod()
private void EmitGetBinderOptionsHelper()
{
- _writer.WriteBlock($$"""
+ _writer.WriteLine($$"""
public static {{Identifier.BinderOptions}}? {{Identifier.GetBinderOptions}}({{MinimalDisplayString.NullableActionOfBinderOptions}} {{Identifier.configureOptions}})
{
if ({{Identifier.configureOptions}} is null)
@@ -593,22 +591,17 @@ private void EmitPrimitiveParseMethod(ParsableFromStringSpec type)
}
}
- _writer.WriteBlock($$"""
- public static {{typeDisplayString}} {{type.ParseMethodName}}(string {{Identifier.value}}, Func {{Identifier.getPath}})
- {
- try
- {
- return {{parsedValueExpr}};
- """);
-
string exceptionArg1 = string.Format(ExceptionMessages.FailedBinding, $"{{{Identifier.getPath}()}}", $"{{typeof({typeDisplayString})}}");
- _writer.WriteBlock($$"""
- }
- catch ({{innerExceptionTypeDisplayString}} {{Identifier.exception}})
- {
- throw new {{GetInvalidOperationDisplayName()}}($"{{exceptionArg1}}", {{Identifier.exception}});
- }
+ EmitStartBlock($"public static {typeDisplayString} {type.ParseMethodName}(string {Identifier.value}, Func {Identifier.getPath})");
+ EmitEndBlock($$"""
+ try
+ {
+ return {{parsedValueExpr}};
+ }
+ catch ({{innerExceptionTypeDisplayString}} {{Identifier.exception}})
+ {
+ throw new {{GetInvalidOperationDisplayName()}}($"{{exceptionArg1}}", {{Identifier.exception}});
}
""");
}
@@ -622,7 +615,7 @@ private void EmitPopulationImplForArray(EnumerableSpec type)
EmitBindCoreCall(concreteType, tempIdentifier, Identifier.configuration, InitializationKind.Declaration);
// Resize array and add binded elements.
- _writer.WriteBlock($$"""
+ _writer.WriteLine($$"""
{{Identifier.Int32}} {{Identifier.originalCount}} = {{Identifier.obj}}.{{Identifier.Length}};
{{Identifier.Array}}.{{Identifier.Resize}}(ref {{Identifier.obj}}, {{Identifier.originalCount}} + {{tempIdentifier}}.{{Identifier.Count}});
{{tempIdentifier}}.{{Identifier.CopyTo}}({{Identifier.obj}}, {{Identifier.originalCount}});
@@ -633,7 +626,7 @@ private void EmitPopulationImplForEnumerableWithAdd(EnumerableSpec type)
{
EmitCollectionCastIfRequired(type, out string objIdentifier);
- Emit_Foreach_Section_In_ConfigChildren_BlockHeader();
+ Emit_Foreach_Section_In_ConfigChildren_StartBlock();
TypeSpec elementType = type.ElementType;
@@ -653,14 +646,14 @@ private void EmitPopulationImplForEnumerableWithAdd(EnumerableSpec type)
_writer.WriteLine($"{objIdentifier}.{Identifier.Add}({Identifier.value});");
}
- _writer.WriteBlockEnd();
+ EmitEndBlock();
}
private void EmitBindCoreImplForDictionary(DictionarySpec type)
{
EmitCollectionCastIfRequired(type, out string objIdentifier);
- Emit_Foreach_Section_In_ConfigChildren_BlockHeader();
+ Emit_Foreach_Section_In_ConfigChildren_StartBlock();
ParsableFromStringSpec keyType = type.KeyType;
TypeSpec elementType = type.ElementType;
@@ -710,9 +703,9 @@ void Emit_BindAndAddLogic_ForElement(string parsedKeyExpr)
conditionToUseExistingElement += $" && {expressionForElementIsNotNull}";
}
- _writer.WriteBlockStart($"if (!({conditionToUseExistingElement}))");
+ EmitStartBlock($"if (!({conditionToUseExistingElement}))");
EmitObjectInit(elementType, Identifier.element, InitializationKind.SimpleAssignment, Identifier.section);
- _writer.WriteBlockEnd();
+ EmitEndBlock();
if (elementType is CollectionSpec { InitializationStrategy: InitializationStrategy.ParameterizedConstructor or InitializationStrategy.ToEnumerableMethod } collectionSpec)
{
@@ -723,7 +716,7 @@ void Emit_BindAndAddLogic_ForElement(string parsedKeyExpr)
? $"new {collectionSpec.ConcreteType.MinimalDisplayString}({Identifier.element})"
: $"{Identifier.element}.{collectionSpec.ToEnumerableMethodCall!}";
- _writer.WriteBlock($$"""
+ _writer.WriteLine($$"""
else
{
{{Identifier.element}} = {{initExpression}};
@@ -734,10 +727,9 @@ void Emit_BindAndAddLogic_ForElement(string parsedKeyExpr)
EmitBindCoreCall(elementType, Identifier.element, Identifier.section, InitializationKind.None);
_writer.WriteLine($"{objIdentifier}[{parsedKeyExpr}] = {Identifier.element};");
}
-
}
- _writer.WriteBlockEnd();
+ EmitEndBlock();
}
private void EmitBindCoreImplForObject(ObjectSpec type)
@@ -794,7 +786,7 @@ private bool EmitBindImplForMember(
return true;
}
- string sectionParseExpr = $"{GetSectionFromConfigurationExpression(member.ConfigurationKeyName)}";
+ string sectionParseExpr = GetSectionFromConfigurationExpression(member.ConfigurationKeyName);
EmitBlankLineIfRequired();
@@ -807,7 +799,7 @@ private bool EmitBindImplForMember(
string sectionValidationCall = $"{Identifier.AsConfigWithChildren}({sectionParseExpr})";
string sectionIdentifier = GetIncrementalIdentifier(Identifier.section);
- _writer.WriteBlockStart($"if ({sectionValidationCall} is {Identifier.IConfigurationSection} {sectionIdentifier})");
+ EmitStartBlock($"if ({sectionValidationCall} is {Identifier.IConfigurationSection} {sectionIdentifier})");
bool success = !EmitInitException(effectiveMemberType);
if (success)
@@ -815,7 +807,7 @@ private bool EmitBindImplForMember(
EmitBindCoreCallForMember(member, memberAccessExpr, sectionIdentifier, canSet);
}
- _writer.WriteBlockEnd();
+ EmitEndBlock();
return success;
}
@@ -896,18 +888,18 @@ private void EmitCollectionCastIfRequired(CollectionSpec type, out string objIde
if (type.PopulationStrategy is CollectionPopulationStrategy.Cast_Then_Add)
{
objIdentifier = Identifier.temp;
- _writer.WriteBlock($$"""
+ _writer.WriteLine($$"""
if ({{Identifier.obj}} is not {{type.PopulationCastType!.MinimalDisplayString}} {{objIdentifier}})
{
return;
}
""");
- _writer.WriteBlankLine();
+ _writer.WriteLine();
}
}
- private void Emit_Foreach_Section_In_ConfigChildren_BlockHeader() =>
- _writer.WriteBlockStart($"foreach ({Identifier.IConfigurationSection} {Identifier.section} in {Identifier.configuration}.{Identifier.GetChildren}())");
+ private void Emit_Foreach_Section_In_ConfigChildren_StartBlock() =>
+ EmitStartBlock($"foreach ({Identifier.IConfigurationSection} {Identifier.section} in {Identifier.configuration}.{Identifier.GetChildren}())");
private static string GetSectionPathFromConfigurationExpression(string configurationKeyName)
=> $@"{GetSectionFromConfigurationExpression(configurationKeyName)}.{Identifier.Path}";
diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/Helpers.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/Helpers.cs
index 7325c292a0036..e0e6a36aabaa7 100644
--- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/Helpers.cs
+++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/Helpers.cs
@@ -129,11 +129,43 @@ private bool ShouldEmitBinders() =>
ShouldEmitMethods(MethodsToGen_Extensions_OptionsBuilder.Any) ||
ShouldEmitMethods(MethodsToGen_Extensions_ServiceCollection.Any);
+ ///
+ /// Starts a block of source code.
+ ///
+ /// Source to write after the open brace.
+ public void EmitStartBlock(string? source = null)
+ {
+ if (source is not null)
+ {
+ _writer.WriteLine(source);
+ }
+
+ _writer.WriteLine("{");
+ _writer.Indentation++;
+ }
+
+ ///
+ /// Ends a block of source code.
+ ///
+ /// Source to write before the close brace.
+ /// Trailing source after the end brace, e.g. ";" to end an init statement.
+ 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()
{
if (_emitBlankLineBeforeNextStatement)
{
- _writer.WriteBlankLine();
+ _writer.WriteLine();
}
_emitBlankLineBeforeNextStatement = true;
@@ -153,14 +185,14 @@ private void EmitCheckForNullArgument_WithBlankLine(string paramName)
? "global::System.ArgumentNullException"
: "ArgumentNullException";
- _writer.WriteBlock($$"""
+ _writer.WriteLine($$"""
if ({{paramName}} is null)
{
throw new {{exceptionTypeDisplayString}}(nameof({{paramName}}));
}
""");
- _writer.WriteBlankLine();
+ _writer.WriteLine();
}
private bool EmitInitException(TypeSpec type)
@@ -176,14 +208,13 @@ private bool EmitInitException(TypeSpec type)
return false;
}
- private void EmitRootBindingClassBlockStart(string className)
+ private void EmitRootBindingClassStartBlock(string className)
{
EmitBlankLineIfRequired();
- _writer.WriteBlock($$"""
+ EmitStartBlock($$"""
/// Generated helper providing an AOT and linking compatible implementation for configuration binding.
{{GetGeneratedCodeAttributeSrc()}}
internal static class {{className}}
- {
""");
_emitBlankLineBeforeNextStatement = false;
diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/OptionsBuilderConfigurationExtensions.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/OptionsBuilderConfigurationExtensions.cs
index 0055b2bf127c0..71d0b6989dd97 100644
--- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/OptionsBuilderConfigurationExtensions.cs
+++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/OptionsBuilderConfigurationExtensions.cs
@@ -16,12 +16,12 @@ private void EmitBinder_Extensions_OptionsBuilder()
return;
}
- EmitRootBindingClassBlockStart(Identifier.GeneratedOptionsBuilderBinder);
+ EmitRootBindingClassStartBlock(Identifier.GeneratedOptionsBuilderBinder);
EmitBindMethods_Extensions_OptionsBuilder();
EmitBindConfigurationMethod();
- _writer.WriteBlockEnd();
+ EmitEndBlock();
}
private void EmitBindMethods_Extensions_OptionsBuilder()
@@ -36,24 +36,24 @@ private void EmitBindMethods_Extensions_OptionsBuilder()
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.WriteBlockEnd();
+ EmitEndBlock();
}
- EmitMethodBlockStart(
+ EmitMethodStartBlock(
"Bind",
paramList + $", {FullyQualifiedDisplayString.ActionOfBinderOptions}? {Identifier.configureOptions}",
documentation);
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}});
return {{Identifier.optionsBuilder}};
""");
- _writer.WriteBlockEnd();
+ EmitEndBlock();
}
private void EmitBindConfigurationMethod()
@@ -66,37 +66,37 @@ private void EmitBindConfigurationMethod()
const string documentation = $@"/// Registers the dependency injection container to bind against the obtained from the DI service provider.";
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.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($$"""
- {{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}});
- """);
+ _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.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}});
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}";
EmitBlankLineIfRequired();
_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");
}
}
}
diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/OptionsConfigurationServiceCollectionExtensions.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/OptionsConfigurationServiceCollectionExtensions.cs
index 5b4edc93b8a51..f4cd4800df123 100644
--- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/OptionsConfigurationServiceCollectionExtensions.cs
+++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/OptionsConfigurationServiceCollectionExtensions.cs
@@ -9,14 +9,14 @@ private sealed partial class Emitter
{
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))
{
return;
}
- EmitRootBindingClassBlockStart(Identifier.GeneratedServiceCollectionBinder);
+ EmitRootBindingClassStartBlock(Identifier.GeneratedServiceCollectionBinder);
const string defaultNameExpr = "string.Empty";
const string configureMethodString = $"global::{Identifier.GeneratedServiceCollectionBinder}.{Identifier.Configure}";
@@ -24,56 +24,56 @@ private void EmitBinder_Extensions_ServiceCollection()
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.WriteBlockEnd();
+ EmitEndBlock();
}
if (ShouldEmitMethods(MethodsToGen_Extensions_ServiceCollection.Configure_T_name))
{
- EmitBlockStart(
+ EmitStartMethod(
paramList: $"string? {Identifier.name}, " + configParam);
_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))
{
- EmitBlockStart(
+ EmitStartMethod(
paramList: configParam + $", {FullyQualifiedDisplayString.ActionOfBinderOptions}? {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 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.configuration);
-
- _writer.WriteBlock($$"""
+ _writer.WriteLine($$"""
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}}));
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;
}
- private void EmitBlockStart(string paramList)
+ private void EmitStartMethod(string paramList)
{
paramList = $"this {FullyQualifiedDisplayString.IServiceCollection} {Identifier.services}, {paramList}";
EmitBlankLineIfRequired();
- _writer.WriteBlock($$"""
- /// Registers a configuration instance which TOptions will bind against.
- public static {{FullyQualifiedDisplayString.IServiceCollection}} {{Identifier.Configure}}<{{Identifier.TOptions}}>({{paramList}}) where {{Identifier.TOptions}} : class
- {
- """);
+ EmitStartBlock($$"""
+ /// Registers a configuration instance which TOptions will bind against.
+ public static {{FullyQualifiedDisplayString.IServiceCollection}} {{Identifier.Configure}}<{{Identifier.TOptions}}>({{paramList}}) where {{Identifier.TOptions}} : class
+ """);
}
}
}
diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/SourceWriter.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/SourceWriter.cs
deleted file mode 100644
index f610209874c7d..0000000000000
--- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/SourceWriter.cs
+++ /dev/null
@@ -1,118 +0,0 @@
-// 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 remainingText = source.AsSpan();
-
- do
- {
- ReadOnlySpan 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 GetNextLine(ref ReadOnlySpan remainingText, out bool isFinalLine)
- {
- if (remainingText.IsEmpty)
- {
- isFinalLine = true;
- return default;
- }
-
- ReadOnlySpan next;
- ReadOnlySpan 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 source)
- {
- _sb.Append(' ', 4 * _indentation);
- fixed (char* ptr = source)
- {
- _sb.Append(ptr, source.Length);
- WriteBlankLine();
- }
- }
- }
-}
diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Microsoft.Extensions.Configuration.Binder.SourceGeneration.csproj b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Microsoft.Extensions.Configuration.Binder.SourceGeneration.csproj
index f1c71a5575c23..63f59a53d1d91 100644
--- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Microsoft.Extensions.Configuration.Binder.SourceGeneration.csproj
+++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Microsoft.Extensions.Configuration.Binder.SourceGeneration.csproj
@@ -21,6 +21,7 @@
+
@@ -36,7 +37,6 @@
-
diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Collections.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Collections.generated.txt
index f0b2ffb49b486..1e593a47c1d2f 100644
--- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Collections.generated.txt
+++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Collections.generated.txt
@@ -235,6 +235,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true)
{
List? temp = null;
+
foreach (IConfigurationSection section in configuration.GetChildren())
{
if (!keys.Value.Contains(section.Key))
@@ -242,6 +243,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List()).Add($"'{section.Key}'");
}
}
+
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)}");
@@ -273,12 +275,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
return null;
}
+
BinderOptions binderOptions = new();
configureOptions(binderOptions);
+
if (binderOptions.BindNonPublicProperties)
{
throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.");
}
+
return binderOptions;
}
diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind.generated.txt
index 260a7ad627951..e5d1e51afaaa4 100644
--- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind.generated.txt
+++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind.generated.txt
@@ -126,6 +126,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true)
{
List? temp = null;
+
foreach (IConfigurationSection section in configuration.GetChildren())
{
if (!keys.Value.Contains(section.Key))
@@ -133,6 +134,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List()).Add($"'{section.Key}'");
}
}
+
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)}");
@@ -155,12 +157,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
return null;
}
+
BinderOptions binderOptions = new();
configureOptions(binderOptions);
+
if (binderOptions.BindNonPublicProperties)
{
throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.");
}
+
return binderOptions;
}
diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance.generated.txt
index ecc9953f810c1..31354af58276b 100644
--- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance.generated.txt
+++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance.generated.txt
@@ -120,6 +120,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true)
{
List? temp = null;
+
foreach (IConfigurationSection section in configuration.GetChildren())
{
if (!keys.Value.Contains(section.Key))
@@ -127,6 +128,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List()).Add($"'{section.Key}'");
}
}
+
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)}");
diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance_BinderOptions.generated.txt
index 6132d8d5e2b0b..653ac975652aa 100644
--- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance_BinderOptions.generated.txt
+++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Instance_BinderOptions.generated.txt
@@ -120,6 +120,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true)
{
List? temp = null;
+
foreach (IConfigurationSection section in configuration.GetChildren())
{
if (!keys.Value.Contains(section.Key))
@@ -127,6 +128,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List()).Add($"'{section.Key}'");
}
}
+
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)}");
@@ -149,12 +151,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
return null;
}
+
BinderOptions binderOptions = new();
configureOptions(binderOptions);
+
if (binderOptions.BindNonPublicProperties)
{
throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.");
}
+
return binderOptions;
}
diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Key_Instance.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Key_Instance.generated.txt
index 00570279261ad..575822f5659e8 100644
--- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Key_Instance.generated.txt
+++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Bind_Key_Instance.generated.txt
@@ -120,6 +120,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true)
{
List? temp = null;
+
foreach (IConfigurationSection section in configuration.GetChildren())
{
if (!keys.Value.Contains(section.Key))
@@ -127,6 +128,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List()).Add($"'{section.Key}'");
}
}
+
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)}");
diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get.generated.txt
index edc299c57eb44..9be69f10f5322 100644
--- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get.generated.txt
+++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get.generated.txt
@@ -173,6 +173,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true)
{
List? temp = null;
+
foreach (IConfigurationSection section in configuration.GetChildren())
{
if (!keys.Value.Contains(section.Key))
@@ -180,6 +181,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List()).Add($"'{section.Key}'");
}
}
+
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)}");
@@ -211,12 +213,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
return null;
}
+
BinderOptions binderOptions = new();
configureOptions(binderOptions);
+
if (binderOptions.BindNonPublicProperties)
{
throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.");
}
+
return binderOptions;
}
diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T.generated.txt
index 92768a54a644d..88400019e6b7b 100644
--- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T.generated.txt
+++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T.generated.txt
@@ -141,6 +141,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true)
{
List? temp = null;
+
foreach (IConfigurationSection section in configuration.GetChildren())
{
if (!keys.Value.Contains(section.Key))
@@ -148,6 +149,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List()).Add($"'{section.Key}'");
}
}
+
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)}");
@@ -179,12 +181,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
return null;
}
+
BinderOptions binderOptions = new();
configureOptions(binderOptions);
+
if (binderOptions.BindNonPublicProperties)
{
throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.");
}
+
return binderOptions;
}
diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T_BinderOptions.generated.txt
index 528049d9617e2..aea24cb7ddaed 100644
--- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T_BinderOptions.generated.txt
+++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_T_BinderOptions.generated.txt
@@ -141,6 +141,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true)
{
List? temp = null;
+
foreach (IConfigurationSection section in configuration.GetChildren())
{
if (!keys.Value.Contains(section.Key))
@@ -148,6 +149,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List()).Add($"'{section.Key}'");
}
}
+
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)}");
@@ -179,12 +181,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
return null;
}
+
BinderOptions binderOptions = new();
configureOptions(binderOptions);
+
if (binderOptions.BindNonPublicProperties)
{
throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.");
}
+
return binderOptions;
}
diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf.generated.txt
index 01a865f14b23c..16a98c931a705 100644
--- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf.generated.txt
+++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf.generated.txt
@@ -69,6 +69,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true)
{
List? temp = null;
+
foreach (IConfigurationSection section in configuration.GetChildren())
{
if (!keys.Value.Contains(section.Key))
@@ -76,6 +77,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List()).Add($"'{section.Key}'");
}
}
+
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)}");
@@ -107,12 +109,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
return null;
}
+
BinderOptions binderOptions = new();
configureOptions(binderOptions);
+
if (binderOptions.BindNonPublicProperties)
{
throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.");
}
+
return binderOptions;
}
diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf_BinderOptions.generated.txt
index 620a6049fbb85..8d1ee9ed3cd9a 100644
--- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf_BinderOptions.generated.txt
+++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ConfigurationBinder/Get_TypeOf_BinderOptions.generated.txt
@@ -69,6 +69,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true)
{
List? temp = null;
+
foreach (IConfigurationSection section in configuration.GetChildren())
{
if (!keys.Value.Contains(section.Key))
@@ -76,6 +77,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List()).Add($"'{section.Key}'");
}
}
+
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)}");
@@ -107,12 +109,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
return null;
}
+
BinderOptions binderOptions = new();
configureOptions(binderOptions);
+
if (binderOptions.BindNonPublicProperties)
{
throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.");
}
+
return binderOptions;
}
diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/BindConfiguration.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/BindConfiguration.generated.txt
index 2c61207f45369..6500dc091fccc 100644
--- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/BindConfiguration.generated.txt
+++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/BindConfiguration.generated.txt
@@ -116,6 +116,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true)
{
List? temp = null;
+
foreach (IConfigurationSection section in configuration.GetChildren())
{
if (!keys.Value.Contains(section.Key))
@@ -123,6 +124,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List()).Add($"'{section.Key}'");
}
}
+
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)}");
@@ -154,12 +156,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
return null;
}
+
BinderOptions binderOptions = new();
configureOptions(binderOptions);
+
if (binderOptions.BindNonPublicProperties)
{
throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.");
}
+
return binderOptions;
}
diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T.generated.txt
index a496d89b0000d..7d5271b0a17a7 100644
--- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T.generated.txt
+++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T.generated.txt
@@ -134,6 +134,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true)
{
List? temp = null;
+
foreach (IConfigurationSection section in configuration.GetChildren())
{
if (!keys.Value.Contains(section.Key))
@@ -141,6 +142,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List()).Add($"'{section.Key}'");
}
}
+
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)}");
@@ -172,12 +174,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
return null;
}
+
BinderOptions binderOptions = new();
configureOptions(binderOptions);
+
if (binderOptions.BindNonPublicProperties)
{
throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.");
}
+
return binderOptions;
}
diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T_BinderOptions.generated.txt
index 23a3f5028245c..315c9e3846243 100644
--- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T_BinderOptions.generated.txt
+++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/OptionsBuilder/Bind_T_BinderOptions.generated.txt
@@ -128,6 +128,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true)
{
List? temp = null;
+
foreach (IConfigurationSection section in configuration.GetChildren())
{
if (!keys.Value.Contains(section.Key))
@@ -135,6 +136,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List()).Add($"'{section.Key}'");
}
}
+
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)}");
@@ -166,12 +168,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
return null;
}
+
BinderOptions binderOptions = new();
configureOptions(binderOptions);
+
if (binderOptions.BindNonPublicProperties)
{
throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.");
}
+
return binderOptions;
}
diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Primitives.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Primitives.generated.txt
index c38f1fd39c525..2432136175701 100644
--- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Primitives.generated.txt
+++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/Primitives.generated.txt
@@ -174,6 +174,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true)
{
List? temp = null;
+
foreach (IConfigurationSection section in configuration.GetChildren())
{
if (!keys.Value.Contains(section.Key))
@@ -181,6 +182,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List()).Add($"'{section.Key}'");
}
}
+
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)}");
diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T.generated.txt
index c5717e3fc8333..13e96463ef1a0 100644
--- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T.generated.txt
+++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T.generated.txt
@@ -179,6 +179,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true)
{
List? temp = null;
+
foreach (IConfigurationSection section in configuration.GetChildren())
{
if (!keys.Value.Contains(section.Key))
@@ -186,6 +187,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List()).Add($"'{section.Key}'");
}
}
+
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)}");
@@ -217,12 +219,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
return null;
}
+
BinderOptions binderOptions = new();
configureOptions(binderOptions);
+
if (binderOptions.BindNonPublicProperties)
{
throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.");
}
+
return binderOptions;
}
diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_BinderOptions.generated.txt
index 1b1405c2fc5c5..e2c8faaa9ccf3 100644
--- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_BinderOptions.generated.txt
+++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_BinderOptions.generated.txt
@@ -179,6 +179,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true)
{
List? temp = null;
+
foreach (IConfigurationSection section in configuration.GetChildren())
{
if (!keys.Value.Contains(section.Key))
@@ -186,6 +187,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List()).Add($"'{section.Key}'");
}
}
+
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)}");
@@ -217,12 +219,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
return null;
}
+
BinderOptions binderOptions = new();
configureOptions(binderOptions);
+
if (binderOptions.BindNonPublicProperties)
{
throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.");
}
+
return binderOptions;
}
diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name.generated.txt
index 26cb4aacd72d5..17d5050baf822 100644
--- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name.generated.txt
+++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name.generated.txt
@@ -179,6 +179,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true)
{
List? temp = null;
+
foreach (IConfigurationSection section in configuration.GetChildren())
{
if (!keys.Value.Contains(section.Key))
@@ -186,6 +187,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List()).Add($"'{section.Key}'");
}
}
+
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)}");
@@ -217,12 +219,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
return null;
}
+
BinderOptions binderOptions = new();
configureOptions(binderOptions);
+
if (binderOptions.BindNonPublicProperties)
{
throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.");
}
+
return binderOptions;
}
diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name_BinderOptions.generated.txt
index 53f8ead3ed587..a23f9b26a7e5f 100644
--- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name_BinderOptions.generated.txt
+++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/ServiceCollection/Configure_T_name_BinderOptions.generated.txt
@@ -173,6 +173,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (binderOptions?.ErrorOnUnknownConfiguration is true)
{
List? temp = null;
+
foreach (IConfigurationSection section in configuration.GetChildren())
{
if (!keys.Value.Contains(section.Key))
@@ -180,6 +181,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
(temp ??= new List()).Add($"'{section.Key}'");
}
}
+
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)}");
@@ -211,12 +213,15 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
return null;
}
+
BinderOptions binderOptions = new();
configureOptions(binderOptions);
+
if (binderOptions.BindNonPublicProperties)
{
throw new global::System.NotSupportedException($"The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.");
}
+
return binderOptions;
}
diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBindingGeneratorTests.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBindingGeneratorTests.cs
index ed93f666b0641..4a8296294d4db 100644
--- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBindingGeneratorTests.cs
+++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/ConfigurationBindingGeneratorTests.cs
@@ -257,8 +257,7 @@ private static async Task VerifyAgainstBaselineUsingFile(
.Split(Environment.NewLine);
var (d, r) = await RunGenerator(testSourceCode, languageVersion);
- bool success = RoslynTestUtils.CompareLines(expectedLines, r[0].SourceText,
- out string errorMessage);
+ bool success = RoslynTestUtils.CompareLines(expectedLines, r[0].SourceText, out string errorMessage);
#if !SKIP_BASELINES
Assert.Single(r);
diff --git a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Emitter.cs b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Emitter.cs
index d1413919c1e2f..5109227a9b12d 100644
--- a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Emitter.cs
+++ b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Emitter.cs
@@ -10,6 +10,7 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Text;
+using SourceGenerators;
namespace System.Text.Json.SourceGeneration
{
diff --git a/src/libraries/System.Text.Json/gen/System.Text.Json.SourceGeneration.targets b/src/libraries/System.Text.Json/gen/System.Text.Json.SourceGeneration.targets
index e14905d814875..aba764b194382 100644
--- a/src/libraries/System.Text.Json/gen/System.Text.Json.SourceGeneration.targets
+++ b/src/libraries/System.Text.Json/gen/System.Text.Json.SourceGeneration.targets
@@ -28,6 +28,8 @@
+
+
@@ -50,13 +52,11 @@
-
-