Skip to content

Commit 5e37570

Browse files
committed
Fix failing test, clean up impl, and address feedback
1 parent 9fd0a7a commit 5e37570

File tree

10 files changed

+94
-84
lines changed

10 files changed

+94
-84
lines changed

src/libraries/Common/src/SourceGenerators/SourceWriter.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,18 +64,14 @@ public void WriteLine(string text)
6464
public SourceText ToSourceText()
6565
{
6666
Debug.Assert(_indentation == 0 && _sb.Length > 0);
67-
return SourceText.From(ToString(), Encoding.UTF8);
67+
return SourceText.From(_sb.ToString(), Encoding.UTF8);
6868
}
6969

70-
public override string ToString() => _sb.ToString();
71-
72-
#region Test utilities.
7370
public void Reset()
7471
{
75-
_indentation = 0;
7672
_sb.Clear();
73+
_indentation = 0;
7774
}
78-
#endregion
7975

8076
private void AddIndentation()
8177
=> _sb.Append(IndentationChar, CharsPerIndentation * _indentation);

src/libraries/Common/tests/Common.Tests.csproj

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
Link="Common\System\Collections\DictionaryExtensions.cs" />
1111
<Compile Include="$(CommonTestPath)System\Security\Cryptography\ByteUtils.cs"
1212
Link="Common\System\Security\Cryptography\ByteUtils.cs" />
13-
<Compile Include="$(CommonTestPath)SourceGenerators\RoslynTestUtils.cs"
14-
Link="Common\System\SourceGenerators\RoslynTestUtils.cs" />
1513
<Compile Include="$(CommonPath)Interop\Linux\cgroups\Interop.cgroups.cs"
1614
Link="Common\Interop\Linux\cgroups\Interop.cgroups.cs" />
1715
<Compile Include="$(CommonPath)Interop\Linux\procfs\Interop.ProcFsStat.cs"

src/libraries/Common/tests/TestUtilities/System/LineEndingsHelper.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,14 @@ namespace System
55
{
66
public static class LineEndingsHelper
77
{
8-
private const string CompiledNewline = @"
8+
public const string CompiledNewline = @"
99
";
10-
private static readonly bool s_consistentNewlines = StringComparer.Ordinal.Equals(CompiledNewline, Environment.NewLine);
10+
public static readonly bool s_consistentNewlines = StringComparer.Ordinal.Equals(CompiledNewline, Environment.NewLine);
11+
12+
static public bool IsNewLineConsistent
13+
{
14+
get { return s_consistentNewlines; }
15+
}
1116

1217
public static string Normalize(string expected)
1318
{

src/libraries/Common/tests/Tests/SourceGenerators/SourceWriterTests.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ public void CanHandleVariousLineEndings()
1414
string testTemplate = "public static void Main(){0}{{{1}\tConsole.WriteLine(\"Hello, world\");{2}}}";
1515
SourceWriter writer = new();
1616

17+
CheckCanWrite(string.Format(testTemplate, "\n", "\n", "\n"));
18+
CheckCanWrite(string.Format(testTemplate, "\r\n", "\r\n", "\r\n"));
19+
CheckCanWrite(string.Format(testTemplate, "\n", "\r\n", "\n"));
20+
1721
// Regression test for https://github.com/dotnet/runtime/issues/88918.
1822
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}");
1923

20-
CheckCanWrite(string.Format(testTemplate, "\n", "\n", "\n"));
21-
CheckCanWrite(string.Format(testTemplate, "\n\r", "\n\r", "\n\r"));
22-
CheckCanWrite(string.Format(testTemplate, "\n", "\n\r", "\n"));
23-
2424
void CheckCanWrite(string source)
2525
{
2626
// No exception expected.

src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Emitter.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,16 @@ private void EmitBindLogicFromString(
132132

133133
if (!checkForNullSectionValue)
134134
{
135-
writeOnSuccess?.Invoke(parsedValueExpr);
135+
InvokeWriteOnSuccess();
136136
}
137137
else
138138
{
139-
EmitStartScope($"if ({sectionValueExpr} is string {nonNull_StringValue_Identifier})");
140-
writeOnSuccess?.Invoke(parsedValueExpr);
141-
EmitEndScope();
139+
EmitStartBlock($"if ({sectionValueExpr} is string {nonNull_StringValue_Identifier})");
140+
InvokeWriteOnSuccess();
141+
EmitEndBlock();
142142
}
143+
144+
void InvokeWriteOnSuccess() => writeOnSuccess?.Invoke(parsedValueExpr);
143145
}
144146

145147
private bool EmitObjectInit(TypeSpec type, string memberAccessExpr, InitializationKind initKind, string configArgExpr)

src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/ConfigurationBinder.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ private void EmitBinder_Extensions_IConfiguration()
2525
}
2626

2727
_emitBlankLineBeforeNextStatement = false;
28-
EmitRootBindingClassStartScope(Identifier.GeneratedConfigurationBinder);
28+
EmitRootBindingClassStartBlock(Identifier.GeneratedConfigurationBinder);
2929

3030
EmitGetMethods();
3131
EmitGetValueMethods();
3232
EmitBindMethods_ConfigurationBinder();
3333

34-
EmitEndScope();
34+
EmitEndBlock();
3535
_emitBlankLineBeforeNextStatement = true;
3636
}
3737

src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Helpers/Emitter/CoreBindingHelper.cs

Lines changed: 36 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ private void Emit_CoreBindingHelper()
2222
_writer.WriteLine();
2323
_emitBlankLineBeforeNextStatement = false;
2424

25-
EmitStartScope($"namespace {ProjectName}");
25+
EmitStartBlock($"namespace {ProjectName}");
2626
EmitHelperUsingStatements();
2727

2828
_writer.WriteLine();
2929

30-
EmitStartScope($$"""
30+
EmitStartBlock($$"""
3131
/// <summary>Provide core binding logic.</summary>
3232
{{GetGeneratedCodeAttributeSrc()}}
3333
file static class {{Identifier.CoreBindingHelper}}
@@ -41,8 +41,8 @@ file static class {{Identifier.CoreBindingHelper}}
4141
EmitInitializeMethods();
4242
EmitHelperMethods();
4343

44-
EmitEndScope(); // End helper class.
45-
EmitEndScope(); // End namespace.
44+
EmitEndBlock(); // End helper class.
45+
EmitEndBlock(); // End namespace.
4646
}
4747

4848
private void EmitHelperUsingStatements()
@@ -87,7 +87,7 @@ private void EmitGetCoreMethod()
8787
}
8888

8989
EmitBlankLineIfRequired();
90-
EmitStartScope($"public static object? {nameof(MethodsToGen_CoreBindingHelper.GetCore)}(this {Identifier.IConfiguration} {Identifier.configuration}, Type {Identifier.type}, Action<{Identifier.BinderOptions}>? {Identifier.configureOptions})");
90+
EmitStartBlock($"public static object? {nameof(MethodsToGen_CoreBindingHelper.GetCore)}(this {Identifier.IConfiguration} {Identifier.configuration}, Type {Identifier.type}, Action<{Identifier.BinderOptions}>? {Identifier.configureOptions})");
9191

9292
EmitCheckForNullArgument_WithBlankLine(Identifier.configuration);
9393

@@ -100,7 +100,7 @@ private void EmitGetCoreMethod()
100100
{
101101
TypeSpecKind kind = type.SpecKind;
102102

103-
EmitStartScope($"if (type == typeof({type.MinimalDisplayString}))");
103+
EmitStartBlock($"if (type == typeof({type.MinimalDisplayString}))");
104104

105105
if (type is ParsableFromStringSpec stringParsableType)
106106
{
@@ -119,12 +119,12 @@ private void EmitGetCoreMethod()
119119
_writer.WriteLine($"return {Identifier.obj};");
120120
}
121121

122-
EmitEndScope();
122+
EmitEndBlock();
123123
_writer.WriteLine();
124124
}
125125

126126
Emit_NotSupportedException_TypeNotDetectedAsInput();
127-
EmitEndScope();
127+
EmitEndBlock();
128128
_emitBlankLineBeforeNextStatement = true;
129129
}
130130

@@ -136,7 +136,7 @@ private void EmitGetValueCoreMethod()
136136
}
137137

138138
EmitBlankLineIfRequired();
139-
EmitStartScope($"public static object? {nameof(MethodsToGen_CoreBindingHelper.GetValueCore)}(this {Identifier.IConfiguration} {Identifier.configuration}, Type {Identifier.type}, string {Identifier.key})");
139+
EmitStartBlock($"public static object? {nameof(MethodsToGen_CoreBindingHelper.GetValueCore)}(this {Identifier.IConfiguration} {Identifier.configuration}, Type {Identifier.type}, string {Identifier.key})");
140140

141141
EmitCheckForNullArgument_WithBlankLine(Identifier.configuration);
142142
_writer.WriteLine($@"{Identifier.IConfigurationSection} {Identifier.section} = {GetSectionFromConfigurationExpression(Identifier.key, addQuotes: false)};");
@@ -153,7 +153,7 @@ private void EmitGetValueCoreMethod()
153153

154154
foreach (TypeSpec type in targetTypes)
155155
{
156-
EmitStartScope($"if ({Identifier.type} == typeof({type.MinimalDisplayString}))");
156+
EmitStartBlock($"if ({Identifier.type} == typeof({type.MinimalDisplayString}))");
157157

158158
EmitBindLogicFromString(
159159
(ParsableFromStringSpec)type.EffectiveType,
@@ -163,12 +163,12 @@ private void EmitGetValueCoreMethod()
163163
checkForNullSectionValue: false,
164164
useIncrementalStringValueIdentifier: false);
165165

166-
EmitEndScope();
166+
EmitEndBlock();
167167
_writer.WriteLine();
168168
}
169169

170170
_writer.WriteLine("return null;");
171-
EmitEndScope();
171+
EmitEndBlock();
172172
_emitBlankLineBeforeNextStatement = true;
173173
}
174174

@@ -181,7 +181,7 @@ private void EmitBindCoreUntypedMethod()
181181

182182
EmitBlankLineIfRequired();
183183

184-
EmitStartScope($"public static void {nameof(MethodsToGen_CoreBindingHelper.BindCoreUntyped)}(this {Identifier.IConfiguration} {Identifier.configuration}, object {Identifier.obj}, Type {Identifier.type}, {MinimalDisplayString.NullableActionOfBinderOptions} {Identifier.configureOptions})");
184+
EmitStartBlock($"public static void {nameof(MethodsToGen_CoreBindingHelper.BindCoreUntyped)}(this {Identifier.IConfiguration} {Identifier.configuration}, object {Identifier.obj}, Type {Identifier.type}, {MinimalDisplayString.NullableActionOfBinderOptions} {Identifier.configureOptions})");
185185

186186
EmitCheckForNullArgument_WithBlankLine(Identifier.configuration);
187187

@@ -192,7 +192,7 @@ private void EmitBindCoreUntypedMethod()
192192

193193
foreach (TypeSpec type in targetTypes)
194194
{
195-
EmitStartScope($"if (type == typeof({type.MinimalDisplayString}))");
195+
EmitStartBlock($"if (type == typeof({type.MinimalDisplayString}))");
196196

197197
TypeSpec effectiveType = type.EffectiveType;
198198
if (!EmitInitException(effectiveType))
@@ -202,12 +202,12 @@ private void EmitBindCoreUntypedMethod()
202202
_writer.WriteLine($"return;");
203203
}
204204

205-
EmitEndScope();
205+
EmitEndBlock();
206206
_writer.WriteLine();
207207
}
208208

209209
Emit_NotSupportedException_TypeNotDetectedAsInput();
210-
EmitEndScope();
210+
EmitEndBlock();
211211
_emitBlankLineBeforeNextStatement = true;
212212
}
213213

@@ -231,7 +231,7 @@ private void EmitBindCoreMethod(TypeSpec type)
231231
Debug.Assert(type.CanInitialize);
232232

233233
string objParameterExpression = $"ref {type.MinimalDisplayString} {Identifier.obj}";
234-
EmitStartScope(@$"public static void {nameof(MethodsToGen_CoreBindingHelper.BindCore)}({Identifier.IConfiguration} {Identifier.configuration}, {objParameterExpression}, {Identifier.BinderOptions}? {Identifier.binderOptions})");
234+
EmitStartBlock(@$"public static void {nameof(MethodsToGen_CoreBindingHelper.BindCore)}({Identifier.IConfiguration} {Identifier.configuration}, {objParameterExpression}, {Identifier.BinderOptions}? {Identifier.binderOptions})");
235235

236236
EmitCheckForNullArgument_WithBlankLine_IfRequired(type.IsValueType);
237237

@@ -257,7 +257,7 @@ private void EmitBindCoreMethod(TypeSpec type)
257257
EmitBindCoreImplForObject((ObjectSpec)effectiveType);
258258
}
259259

260-
EmitEndScope();
260+
EmitEndBlock();
261261
}
262262

263263
private void EmitInitializeMethods()
@@ -282,7 +282,7 @@ private void EmitInitializeMethod(ObjectSpec type)
282282
List<string> ctorArgList = new();
283283
string displayString = type.MinimalDisplayString;
284284

285-
EmitStartScope($"public static {type.MinimalDisplayString} {GetInitalizeMethodDisplayString(type)}({Identifier.IConfiguration} {Identifier.configuration}, {Identifier.BinderOptions}? {Identifier.binderOptions})");
285+
EmitStartBlock($"public static {type.MinimalDisplayString} {GetInitalizeMethodDisplayString(type)}({Identifier.IConfiguration} {Identifier.configuration}, {Identifier.BinderOptions}? {Identifier.binderOptions})");
286286
_emitBlankLineBeforeNextStatement = false;
287287

288288
foreach (ParameterSpec parameter in ctorParams)
@@ -316,17 +316,17 @@ private void EmitInitializeMethod(ObjectSpec type)
316316
}
317317
else
318318
{
319-
EmitStartScope(returnExpression);
319+
EmitStartBlock(returnExpression);
320320
foreach (PropertySpec property in initOnlyProps)
321321
{
322322
string propertyName = property.Name;
323323
_writer.WriteLine($@"{propertyName} = {propertyName},");
324324
}
325-
EmitEndScope(extra: ";");
325+
EmitEndBlock(endBraceTrailingSource: ";");
326326
}
327327

328328
// End method.
329-
EmitEndScope();
329+
EmitEndBlock();
330330
_emitBlankLineBeforeNextStatement = true;
331331

332332
void EmitBindImplForMember(MemberSpec member)
@@ -591,17 +591,14 @@ private void EmitPrimitiveParseMethod(ParsableFromStringSpec type)
591591
}
592592
}
593593

594-
EmitStartScope($"public static {typeDisplayString} {type.ParseMethodName}(string {Identifier.value}, Func<string?> {Identifier.getPath})");
595-
_writer.WriteLine($$"""
594+
string exceptionArg1 = string.Format(ExceptionMessages.FailedBinding, $"{{{Identifier.getPath}()}}", $"{{typeof({typeDisplayString})}}");
595+
596+
EmitStartBlock($"public static {typeDisplayString} {type.ParseMethodName}(string {Identifier.value}, Func<string?> {Identifier.getPath})");
597+
EmitEndBlock($$"""
596598
try
597599
{
598600
return {{parsedValueExpr}};
599601
}
600-
""");
601-
602-
string exceptionArg1 = string.Format(ExceptionMessages.FailedBinding, $"{{{Identifier.getPath}()}}", $"{{typeof({typeDisplayString})}}");
603-
604-
EmitEndScope($$"""
605602
catch ({{innerExceptionTypeDisplayString}} {{Identifier.exception}})
606603
{
607604
throw new {{GetInvalidOperationDisplayName()}}($"{{exceptionArg1}}", {{Identifier.exception}});
@@ -629,7 +626,7 @@ private void EmitPopulationImplForEnumerableWithAdd(EnumerableSpec type)
629626
{
630627
EmitCollectionCastIfRequired(type, out string objIdentifier);
631628

632-
Emit_Foreach_Section_In_ConfigChildren_StartScope();
629+
Emit_Foreach_Section_In_ConfigChildren_StartBlock();
633630

634631
TypeSpec elementType = type.ElementType;
635632

@@ -649,14 +646,14 @@ private void EmitPopulationImplForEnumerableWithAdd(EnumerableSpec type)
649646
_writer.WriteLine($"{objIdentifier}.{Identifier.Add}({Identifier.value});");
650647
}
651648

652-
EmitEndScope();
649+
EmitEndBlock();
653650
}
654651

655652
private void EmitBindCoreImplForDictionary(DictionarySpec type)
656653
{
657654
EmitCollectionCastIfRequired(type, out string objIdentifier);
658655

659-
Emit_Foreach_Section_In_ConfigChildren_StartScope();
656+
Emit_Foreach_Section_In_ConfigChildren_StartBlock();
660657

661658
ParsableFromStringSpec keyType = type.KeyType;
662659
TypeSpec elementType = type.ElementType;
@@ -706,9 +703,9 @@ void Emit_BindAndAddLogic_ForElement(string parsedKeyExpr)
706703
conditionToUseExistingElement += $" && {expressionForElementIsNotNull}";
707704
}
708705

709-
EmitStartScope($"if (!({conditionToUseExistingElement}))");
706+
EmitStartBlock($"if (!({conditionToUseExistingElement}))");
710707
EmitObjectInit(elementType, Identifier.element, InitializationKind.SimpleAssignment, Identifier.section);
711-
EmitEndScope();
708+
EmitEndBlock();
712709

713710
if (elementType is CollectionSpec { InitializationStrategy: InitializationStrategy.ParameterizedConstructor or InitializationStrategy.ToEnumerableMethod } collectionSpec)
714711
{
@@ -732,7 +729,7 @@ void Emit_BindAndAddLogic_ForElement(string parsedKeyExpr)
732729
}
733730
}
734731

735-
EmitEndScope();
732+
EmitEndBlock();
736733
}
737734

738735
private void EmitBindCoreImplForObject(ObjectSpec type)
@@ -802,15 +799,15 @@ private bool EmitBindImplForMember(
802799
string sectionValidationCall = $"{Identifier.AsConfigWithChildren}({sectionParseExpr})";
803800
string sectionIdentifier = GetIncrementalIdentifier(Identifier.section);
804801

805-
EmitStartScope($"if ({sectionValidationCall} is {Identifier.IConfigurationSection} {sectionIdentifier})");
802+
EmitStartBlock($"if ({sectionValidationCall} is {Identifier.IConfigurationSection} {sectionIdentifier})");
806803

807804
bool success = !EmitInitException(effectiveMemberType);
808805
if (success)
809806
{
810807
EmitBindCoreCallForMember(member, memberAccessExpr, sectionIdentifier, canSet);
811808
}
812809

813-
EmitEndScope();
810+
EmitEndBlock();
814811
return success;
815812
}
816813

@@ -901,8 +898,8 @@ private void EmitCollectionCastIfRequired(CollectionSpec type, out string objIde
901898
}
902899
}
903900

904-
private void Emit_Foreach_Section_In_ConfigChildren_StartScope() =>
905-
EmitStartScope($"foreach ({Identifier.IConfigurationSection} {Identifier.section} in {Identifier.configuration}.{Identifier.GetChildren}())");
901+
private void Emit_Foreach_Section_In_ConfigChildren_StartBlock() =>
902+
EmitStartBlock($"foreach ({Identifier.IConfigurationSection} {Identifier.section} in {Identifier.configuration}.{Identifier.GetChildren}())");
906903

907904
private static string GetSectionPathFromConfigurationExpression(string configurationKeyName)
908905
=> $@"{GetSectionFromConfigurationExpression(configurationKeyName)}.{Identifier.Path}";

0 commit comments

Comments
 (0)