diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingSourceGenerator.Emitter.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingSourceGenerator.Emitter.cs
index b969227138f98d..046b518f70a45d 100644
--- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingSourceGenerator.Emitter.cs
+++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingSourceGenerator.Emitter.cs
@@ -4,10 +4,8 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
-using System.Text;
using System.Text.RegularExpressions;
using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.Text;
namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
@@ -79,8 +77,7 @@ public void Emit()
EmitGenerationNamespaceAndHelpers();
- SourceText source = SourceText.From(_writer.GetSource(), Encoding.UTF8);
- _context.AddSource($"{Identifier.GeneratedConfigurationBinder}.g.cs", source);
+ _context.AddSource($"{Identifier.GeneratedConfigurationBinder}.g.cs", _writer.ToSourceText());
}
private void EmitConfigureMethod()
@@ -275,10 +272,10 @@ private void EmitBindCoreImplForArray(EnumerableSpec type)
// Resize array and copy fill with additional
_writer.WriteBlock($$"""
-{{Identifier.Int32}} {{Identifier.originalCount}} = {{Identifier.obj}}.{{Identifier.Length}};
-{{Identifier.Array}}.{{Identifier.Resize}}(ref {{Identifier.obj}}, {{Identifier.originalCount}} + {{tempVarName}}.{{Identifier.Count}});
-{{tempVarName}}.{{Identifier.CopyTo}}({{Identifier.obj}}, {{Identifier.originalCount}});
-""");
+ {{Identifier.Int32}} {{Identifier.originalCount}} = {{Identifier.obj}}.{{Identifier.Length}};
+ {{Identifier.Array}}.{{Identifier.Resize}}(ref {{Identifier.obj}}, {{Identifier.originalCount}} + {{tempVarName}}.{{Identifier.Count}});
+ {{tempVarName}}.{{Identifier.CopyTo}}({{Identifier.obj}}, {{Identifier.originalCount}});
+ """);
}
private void EmitBindCoreImplForDictionary(DictionarySpec type)
@@ -675,11 +672,11 @@ private void EmitObjectInit(TypeSpec type, string expressionForMemberAccess, Ini
private void EmitIConfigurationHasValueOrChildrenCheck()
{
_writer.WriteBlock($$"""
-if (!{{GetHelperMethodDisplayString(Identifier.HasValueOrChildren)}}({{Identifier.configuration}}))
-{
- return default;
-}
-""");
+ if (!{{GetHelperMethodDisplayString(Identifier.HasValueOrChildren)}}({{Identifier.configuration}}))
+ {
+ return default;
+ }
+ """);
_writer.WriteBlankLine();
}
@@ -700,31 +697,29 @@ private void EmitHelperMethods()
private void EmitHasValueOrChildrenMethod()
{
_writer.WriteBlock($$"""
-public static bool {{Identifier.HasValueOrChildren}}({{Identifier.IConfiguration}} {{Identifier.configuration}})
-{
- if (({{Identifier.configuration}} as {{Identifier.IConfigurationSection}})?.{{Identifier.Value}} is not null)
- {
- return true;
- }
-
- return {{Identifier.HasChildren}}({{Identifier.configuration}});
-}
-""");
+ public static bool {{Identifier.HasValueOrChildren}}({{Identifier.IConfiguration}} {{Identifier.configuration}})
+ {
+ if (({{Identifier.configuration}} as {{Identifier.IConfigurationSection}})?.{{Identifier.Value}} is not null)
+ {
+ return true;
+ }
+ return {{Identifier.HasChildren}}({{Identifier.configuration}});
+ }
+ """);
}
private void EmitHasChildrenMethod()
{
_writer.WriteBlock($$"""
-public static bool {{Identifier.HasChildren}}({{Identifier.IConfiguration}} {{Identifier.configuration}})
-{
- foreach ({{Identifier.IConfigurationSection}} {{Identifier.section}} in {{Identifier.configuration}}.{{Identifier.GetChildren}}())
- {
- return true;
- }
-
- return false;
-}
-""");
+ public static bool {{Identifier.HasChildren}}({{Identifier.IConfiguration}} {{Identifier.configuration}})
+ {
+ foreach ({{Identifier.IConfigurationSection}} {{Identifier.section}} in {{Identifier.configuration}}.{{Identifier.GetChildren}}())
+ {
+ return true;
+ }
+ return false;
+ }
+ """);
}
private void EmitVarDeclaration(TypeSpec type, string varName) => _writer.WriteLine($"{type.MinimalDisplayString} {varName};");
@@ -747,11 +742,11 @@ private void EmitCastToIConfigurationSection()
}
_writer.WriteBlock($$"""
-if ({{Identifier.configuration}} is not {{sectionTypeDisplayString}} {{Identifier.section}})
-{
- throw new {{exceptionTypeDisplayString}}();
-}
-""");
+ if ({{Identifier.configuration}} is not {{sectionTypeDisplayString}} {{Identifier.section}})
+ {
+ throw new {{exceptionTypeDisplayString}}();
+ }
+ """);
}
private void Emit_NotSupportedException_UnableToBindType(string reason, string typeDisplayString = "{typeof(T)}") =>
@@ -772,11 +767,11 @@ private void EmitCheckForNullArgument_WithBlankLine(string argName, bool useFull
: Identifier.ArgumentNullException;
_writer.WriteBlock($$"""
-if ({{argName}} is null)
-{
- throw new {{exceptionTypeDisplayString}}(nameof({{argName}}));
-}
-""");
+ if ({{argName}} is null)
+ {
+ throw new {{exceptionTypeDisplayString}}(nameof({{argName}}));
+ }
+ """);
_writer.WriteBlankLine();
}
diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingSourceGenerator.Helpers.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingSourceGenerator.Helpers.cs
index 36feeb419aff55..0556d13cbd323a 100644
--- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingSourceGenerator.Helpers.cs
+++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingSourceGenerator.Helpers.cs
@@ -5,6 +5,7 @@
using System.Diagnostics;
using System.Text;
using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.Text;
namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
@@ -107,79 +108,5 @@ private static class TypeFullName
private static bool TypesAreEqual(ITypeSymbol first, ITypeSymbol second)
=> first.Equals(second, SymbolEqualityComparer.Default);
-
- private sealed class SourceWriter
- {
- private readonly StringBuilder _sb = new();
- private int _indentationLevel;
-
- public int Length => _sb.Length;
- public int IndentationLevel => _indentationLevel;
-
- public void WriteBlockStart(string? declaration = null)
- {
- if (declaration is not null)
- {
- WriteLine(declaration);
- }
- WriteLine("{");
- _indentationLevel++;
- }
-
- public void WriteBlockEnd(string? extra = null)
- {
- _indentationLevel--;
- Debug.Assert(_indentationLevel > -1);
- WriteLine($"}}{extra}");
- }
-
- public void WriteLine(string source)
- {
- _sb.Append(' ', 4 * _indentationLevel);
- _sb.AppendLine(source);
- }
-
- public void WriteBlock(string source)
- {
- foreach (string value in source.Split('\n'))
- {
- string line = value.Trim();
- switch (line)
- {
- case "{":
- {
- WriteBlockStart();
- }
- break;
- case "}":
- {
- WriteBlockEnd();
- }
- break;
- case "":
- {
- WriteBlankLine();
- }
- break;
- default:
- {
- WriteLine(line);
- }
- break;
- }
- }
- }
-
- public void WriteBlankLine() => _sb.AppendLine();
-
- public void RemoveBlankLine()
- {
- int newLineLength = Environment.NewLine.Length;
- int lastNewLineStartIndex = Length - newLineLength;
- _sb.Remove(lastNewLineStartIndex, newLineLength);
- }
-
- public string GetSource() => _sb.ToString();
- }
}
}
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 0c1a30fb76bd07..b37529ecbc87e7 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
@@ -5,9 +5,7 @@
false
true
cs
-
-
-
+ true
$(DefineConstants);LAUNCH_DEBUGGER
@@ -34,6 +32,7 @@
+
diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/SourceWriter.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/SourceWriter.cs
new file mode 100644
index 00000000000000..46aa34852ec50b
--- /dev/null
+++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/SourceWriter.cs
@@ -0,0 +1,129 @@
+// 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 int _indentationLevel;
+
+ public int Length => _sb.Length;
+ public int IndentationLevel => _indentationLevel;
+
+ private static readonly char[] s_newLine = Environment.NewLine.ToCharArray();
+
+ public void WriteBlockStart(string? declaration = null)
+ {
+ if (declaration is not null)
+ {
+ WriteLine(declaration);
+ }
+ WriteLine("{");
+ _indentationLevel++;
+ }
+
+ public void WriteBlockEnd(string? extra = null)
+ {
+ _indentationLevel--;
+ Debug.Assert(_indentationLevel > -1);
+ WriteLine($"}}{extra}");
+ }
+
+ public void WriteLine(string source)
+ {
+ _sb.Append(' ', 4 * _indentationLevel);
+ _sb.AppendLine(source);
+ }
+
+ public unsafe void WriteLine(ReadOnlySpan source)
+ {
+ _sb.Append(' ', 4 * _indentationLevel);
+ fixed (char* ptr = source)
+ {
+ _sb.Append(ptr, source.Length);
+ WriteBlankLine();
+ }
+ }
+
+ 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 void RemoveBlankLine()
+ {
+ int newLineLength = s_newLine.Length;
+ int lastNewLineStartIndex = Length - newLineLength;
+ _sb.Remove(lastNewLineStartIndex, newLineLength);
+ }
+
+ public SourceText ToSourceText()
+ {
+ Debug.Assert(_indentationLevel == 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;
+ }
+ }
+}
diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/TestBindCallGen.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/TestBindCallGen.generated.txt
index 4448061fc15cf2..30c909d2d5e9dd 100644
--- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/TestBindCallGen.generated.txt
+++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/TestBindCallGen.generated.txt
@@ -139,7 +139,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
return true;
}
-
return false;
}
}
diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/TestConfigureCallGen.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/TestConfigureCallGen.generated.txt
index 106a70159245df..6f19224ea7b84d 100644
--- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/TestConfigureCallGen.generated.txt
+++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/TestConfigureCallGen.generated.txt
@@ -119,7 +119,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
return true;
}
-
return HasChildren(configuration);
}
@@ -129,7 +128,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
return true;
}
-
return false;
}
}
diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/TestGetCallGen.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/TestGetCallGen.generated.txt
index 209bfd73e4b7ca..32e497efd4df1d 100644
--- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/TestGetCallGen.generated.txt
+++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/TestGetCallGen.generated.txt
@@ -118,7 +118,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
return true;
}
-
return HasChildren(configuration);
}
@@ -128,7 +127,6 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
return true;
}
-
return false;
}
}