Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Review feedback
  • Loading branch information
steveharter committed Sep 14, 2023
commit 88e1ced0c3a4470b7eced2092f2542e464a9b5ae
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ void EmitMethods(MethodsToGen_ConfigurationBinder method, string additionalParam
EmitCheckForNullArgument_WithBlankLine(Identifier.instance, voidReturn: true);
_writer.WriteLine($$"""
var {{Identifier.typedObj}} = ({{type.EffectiveType.DisplayString}}){{Identifier.instance}};
{{nameof(MethodsToGen_CoreBindingHelper.BindCore)}}({{configExpression}}, ref {{Identifier.typedObj}}, false, {{binderOptionsArg}});
{{nameof(MethodsToGen_CoreBindingHelper.BindCore)}}({{configExpression}}, ref {{Identifier.typedObj}}, defaultValueIfNotFound: false, {{binderOptionsArg}});
""");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,10 +309,6 @@ private void EmitInitializeMethod(ObjectSpec type)
{
if (property.ShouldBindTo && property.MatchingCtorParam is null)
{
// Currently properties don't have an 'else' failure case. Doing that may collide with the
// feature to set properties to their default values if they don't exist in the config section.
Debug.Assert(property.ErrorOnFailedBinding == false);

EmitBindImplForMember(property);
}
}
Expand Down Expand Up @@ -340,8 +336,6 @@ private void EmitInitializeMethod(ObjectSpec type)
void EmitBindImplForMember(MemberSpec member)
{
TypeSpec memberType = member.Type;
bool errorOnFailedBinding = member.ErrorOnFailedBinding;

string parsedMemberDeclarationLhs = $"{memberType.DisplayString} {member.Name}";
string configKeyName = member.ConfigurationKeyName;
string parsedMemberAssignmentLhsExpr;
Expand All @@ -350,7 +344,7 @@ void EmitBindImplForMember(MemberSpec member)
{
case ParsableFromStringSpec { StringParsableTypeKind: StringParsableTypeKind.AssignFromSectionValue }:
{
if (errorOnFailedBinding)
if (member is ParameterSpec parameter && parameter.ErrorOnFailedBinding)
{
string condition = $@"if ({Identifier.configuration}[""{configKeyName}""] is not {parsedMemberDeclarationLhs})";
EmitThrowBlock(condition);
Expand Down Expand Up @@ -384,11 +378,11 @@ void EmitBindImplForMember(MemberSpec member)
parsedMemberAssignmentLhsExpr,
sectionPathExpr: GetSectionPathFromConfigurationExpression(configKeyName),
canSet: true,
firstTimeInitialization: true);
InitializationKind.None);

if (canBindToMember)
{
if (errorOnFailedBinding)
if (member is ParameterSpec parameter && parameter.ErrorOnFailedBinding)
{
// Add exception logic for parameter ctors; must be present in configuration object.
EmitThrowBlock(condition: "else");
Expand Down Expand Up @@ -785,7 +779,7 @@ private void EmitBindCoreImplForObject(ObjectSpec type)
memberAccessExpr: $"{containingTypeRef}.{property.Name}",
GetSectionPathFromConfigurationExpression(property.ConfigurationKeyName),
canSet: property.CanSet,
firstTimeInitialization: false);
InitializationKind.Declaration);
}
}
}
Expand All @@ -795,7 +789,7 @@ private bool EmitBindImplForMember(
string memberAccessExpr,
string sectionPathExpr,
bool canSet,
bool firstTimeInitialization)
InitializationKind initializationKind)
{
TypeSpec effectiveMemberType = member.Type.EffectiveType;

Expand All @@ -807,7 +801,8 @@ private bool EmitBindImplForMember(
{
if (canSet)
{
bool useDefaultValueIfSectionValueIsNull = !firstTimeInitialization &&
bool useDefaultValueIfSectionValueIsNull =
initializationKind == InitializationKind.Declaration &&
member is PropertySpec &&
member.Type.IsValueType &&
member.Type.SpecKind is not TypeSpecKind.Nullable;
Expand Down Expand Up @@ -968,7 +963,7 @@ private void EmitBindingLogic(

void EmitBindingLogic(string instanceToBindExpr, InitializationKind initKind)
{
string bindCoreCall = $@"{nameof(MethodsToGen_CoreBindingHelper.BindCore)}({configArgExpr}, ref {instanceToBindExpr}, {FormatDefaultValueIfNotFound()}, {Identifier.binderOptions});";
string bindCoreCall = $@"{nameof(MethodsToGen_CoreBindingHelper.BindCore)}({configArgExpr}, ref {instanceToBindExpr}, defaultValueIfNotFound: {FormatDefaultValueIfNotFound()}, {Identifier.binderOptions});";

if (type.CanInstantiate)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ private enum InitializationKind
/// The type of defaulting for a property if it does not have a config entry.
/// This should only be applied for "Get" cases, not "Bind" and is also conditioned
/// on the source generated for a particular property as to whether it uses this value.
/// Note this is different than "InitializationKind.Declaration" since it only applied to
/// complex types and not arrays\enumerables.
/// </summary>
private enum ValueDefaulting
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ public MemberSpec(ISymbol member)
}

public string Name { get; }
public bool ErrorOnFailedBinding { get; protected set; }
public string DefaultValueExpr { get; protected set; }

public required TypeSpec Type { get; init; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public ParameterSpec(IParameterSymbol parameter) : base(parameter)
}
}

public bool ErrorOnFailedBinding { get; private set; }

public RefKind RefKind { get; }

public override bool CanGet => false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
if (type == typeof(Program.MyClassWithCustomCollections))
{
var instance = new Program.MyClassWithCustomCollections();
BindCore(configuration, ref instance, true, binderOptions);
BindCore(configuration, ref instance, defaultValueIfNotFound: true, binderOptions);
return instance;
}

Expand Down Expand Up @@ -169,31 +169,31 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
Program.CustomDictionary<string, int>? temp3 = instance.CustomDictionary;
temp3 ??= new Program.CustomDictionary<string, int>();
BindCore(section1, ref temp3, false, binderOptions);
BindCore(section1, ref temp3, defaultValueIfNotFound: false, binderOptions);
instance.CustomDictionary = temp3;
}

if (AsConfigWithChildren(configuration.GetSection("CustomList")) is IConfigurationSection section4)
{
Program.CustomList? temp6 = instance.CustomList;
temp6 ??= new Program.CustomList();
BindCore(section4, ref temp6, false, binderOptions);
BindCore(section4, ref temp6, defaultValueIfNotFound: false, binderOptions);
instance.CustomList = temp6;
}

if (AsConfigWithChildren(configuration.GetSection("IReadOnlyList")) is IConfigurationSection section7)
{
IReadOnlyList<int>? temp9 = instance.IReadOnlyList;
temp9 = temp9 is null ? new List<int>() : new List<int>(temp9);
BindCore(section7, ref temp9, false, binderOptions);
BindCore(section7, ref temp9, defaultValueIfNotFound: false, binderOptions);
instance.IReadOnlyList = temp9;
}

if (AsConfigWithChildren(configuration.GetSection("IReadOnlyDictionary")) is IConfigurationSection section10)
{
IReadOnlyDictionary<string, int>? temp12 = instance.IReadOnlyDictionary;
temp12 = temp12 is null ? new Dictionary<string, int>() : temp12.ToDictionary(pair => pair.Key, pair => pair.Value);
BindCore(section10, ref temp12, false, binderOptions);
BindCore(section10, ref temp12, defaultValueIfNotFound: false, binderOptions);
instance.IReadOnlyDictionary = temp12;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
}

var typedObj = (Program.MyClass)instance;
BindCore(configuration, ref typedObj, false, binderOptions: null);
BindCore(configuration, ref typedObj, defaultValueIfNotFound: false, binderOptions: null);
}

/// <summary>Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively.</summary>
Expand All @@ -63,7 +63,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
}

var typedObj = (Program.MyClass)instance;
BindCore(configuration, ref typedObj, false, GetBinderOptions(configureOptions));
BindCore(configuration, ref typedObj, defaultValueIfNotFound: false, GetBinderOptions(configureOptions));
}

/// <summary>Attempts to bind the given object instance to configuration values by matching property names against configuration keys recursively.</summary>
Expand All @@ -81,7 +81,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
}

var typedObj = (Program.MyClass)instance;
BindCore(configuration.GetSection(key), ref typedObj, false, binderOptions: null);
BindCore(configuration.GetSection(key), ref typedObj, defaultValueIfNotFound: false, binderOptions: null);
}
#endregion IConfiguration extensions.

Expand Down Expand Up @@ -144,23 +144,23 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
List<int>? temp4 = instance.MyList;
temp4 ??= new List<int>();
BindCore(section2, ref temp4, false, binderOptions);
BindCore(section2, ref temp4, defaultValueIfNotFound: false, binderOptions);
instance.MyList = temp4;
}

if (AsConfigWithChildren(configuration.GetSection("MyDictionary")) is IConfigurationSection section5)
{
Dictionary<string, string>? temp7 = instance.MyDictionary;
temp7 ??= new Dictionary<string, string>();
BindCore(section5, ref temp7, false, binderOptions);
BindCore(section5, ref temp7, defaultValueIfNotFound: false, binderOptions);
instance.MyDictionary = temp7;
}

if (AsConfigWithChildren(configuration.GetSection("MyComplexDictionary")) is IConfigurationSection section8)
{
Dictionary<string, Program.MyClass2>? temp10 = instance.MyComplexDictionary;
temp10 ??= new Dictionary<string, Program.MyClass2>();
BindCore(section8, ref temp10, false, binderOptions);
BindCore(section8, ref temp10, defaultValueIfNotFound: false, binderOptions);
instance.MyComplexDictionary = temp10;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
}

var typedObj = (Program.MyClass)instance;
BindCore(configuration, ref typedObj, false, binderOptions: null);
BindCore(configuration, ref typedObj, defaultValueIfNotFound: false, binderOptions: null);
}
#endregion IConfiguration extensions.

Expand Down Expand Up @@ -108,23 +108,23 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
List<int>? temp4 = instance.MyList;
temp4 ??= new List<int>();
BindCore(section2, ref temp4, false, binderOptions);
BindCore(section2, ref temp4, defaultValueIfNotFound: false, binderOptions);
instance.MyList = temp4;
}

if (AsConfigWithChildren(configuration.GetSection("MyDictionary")) is IConfigurationSection section5)
{
Dictionary<string, string>? temp7 = instance.MyDictionary;
temp7 ??= new Dictionary<string, string>();
BindCore(section5, ref temp7, false, binderOptions);
BindCore(section5, ref temp7, defaultValueIfNotFound: false, binderOptions);
instance.MyDictionary = temp7;
}

if (AsConfigWithChildren(configuration.GetSection("MyComplexDictionary")) is IConfigurationSection section8)
{
Dictionary<string, Program.MyClass2>? temp10 = instance.MyComplexDictionary;
temp10 ??= new Dictionary<string, Program.MyClass2>();
BindCore(section8, ref temp10, false, binderOptions);
BindCore(section8, ref temp10, defaultValueIfNotFound: false, binderOptions);
instance.MyComplexDictionary = temp10;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
}

var typedObj = (Program.MyClass)instance;
BindCore(configuration, ref typedObj, false, GetBinderOptions(configureOptions));
BindCore(configuration, ref typedObj, defaultValueIfNotFound: false, GetBinderOptions(configureOptions));
}
#endregion IConfiguration extensions.

Expand Down Expand Up @@ -108,23 +108,23 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
List<int>? temp4 = instance.MyList;
temp4 ??= new List<int>();
BindCore(section2, ref temp4, false, binderOptions);
BindCore(section2, ref temp4, defaultValueIfNotFound: false, binderOptions);
instance.MyList = temp4;
}

if (AsConfigWithChildren(configuration.GetSection("MyDictionary")) is IConfigurationSection section5)
{
Dictionary<string, string>? temp7 = instance.MyDictionary;
temp7 ??= new Dictionary<string, string>();
BindCore(section5, ref temp7, false, binderOptions);
BindCore(section5, ref temp7, defaultValueIfNotFound: false, binderOptions);
instance.MyDictionary = temp7;
}

if (AsConfigWithChildren(configuration.GetSection("MyComplexDictionary")) is IConfigurationSection section8)
{
Dictionary<string, Program.MyClass2>? temp10 = instance.MyComplexDictionary;
temp10 ??= new Dictionary<string, Program.MyClass2>();
BindCore(section8, ref temp10, false, binderOptions);
BindCore(section8, ref temp10, defaultValueIfNotFound: false, binderOptions);
instance.MyComplexDictionary = temp10;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
}

var typedObj = (Program.MyClass)instance;
BindCore(configuration.GetSection(key), ref typedObj, false, binderOptions: null);
BindCore(configuration.GetSection(key), ref typedObj, defaultValueIfNotFound: false, binderOptions: null);
}
#endregion IConfiguration extensions.

Expand Down Expand Up @@ -108,23 +108,23 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
{
List<int>? temp4 = instance.MyList;
temp4 ??= new List<int>();
BindCore(section2, ref temp4, false, binderOptions);
BindCore(section2, ref temp4, defaultValueIfNotFound: false, binderOptions);
instance.MyList = temp4;
}

if (AsConfigWithChildren(configuration.GetSection("MyDictionary")) is IConfigurationSection section5)
{
Dictionary<string, string>? temp7 = instance.MyDictionary;
temp7 ??= new Dictionary<string, string>();
BindCore(section5, ref temp7, false, binderOptions);
BindCore(section5, ref temp7, defaultValueIfNotFound: false, binderOptions);
instance.MyDictionary = temp7;
}

if (AsConfigWithChildren(configuration.GetSection("MyComplexDictionary")) is IConfigurationSection section8)
{
Dictionary<string, Program.MyClass2>? temp10 = instance.MyComplexDictionary;
temp10 ??= new Dictionary<string, Program.MyClass2>();
BindCore(section8, ref temp10, false, binderOptions);
BindCore(section8, ref temp10, defaultValueIfNotFound: false, binderOptions);
instance.MyComplexDictionary = temp10;
}
}
Expand Down
Loading