| __`SYSLIB1100`__ | Configuration binding generator: type is not supported. |
| __`SYSLIB1101`__ | Configuration binding generator: property on type is not supported. |
| __`SYSLIB1102`__ | Configuration binding generator: project's language version must be at least C# 11.|
-| __`SYSLIB1103`__ | *_`SYSLIB1100`-`SYSLIB1118` reserved for Microsoft.Extensions.Configuration.Binder.SourceGeneration.* |
-| __`SYSLIB1104`__ | *_`SYSLIB1100`-`SYSLIB1118` reserved for Microsoft.Extensions.Configuration.Binder.SourceGeneration.* |
+| __`SYSLIB1103`__ | Configuration binding generator: value types are invalid inputs to configuration 'Bind' methods.* |
+| __`SYSLIB1104`__ | Configuration binding generator: Generator cannot determine the target configuration type.* |
| __`SYSLIB1105`__ | *_`SYSLIB1100`-`SYSLIB1118` reserved for Microsoft.Extensions.Configuration.Binder.SourceGeneration.* |
| __`SYSLIB1106`__ | *_`SYSLIB1100`-`SYSLIB1118` reserved for Microsoft.Extensions.Configuration.Binder.SourceGeneration.* |
| __`SYSLIB1107`__ | *_`SYSLIB1100`-`SYSLIB1118` reserved for Microsoft.Extensions.Configuration.Binder.SourceGeneration.* |
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
-using System.Runtime.CompilerServices;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Operations;
{
public sealed partial class ConfigurationBindingGenerator
{
- private sealed class Parser
+ private sealed partial class Parser
{
private readonly SourceProductionContext _context;
private readonly KnownTypeSymbols _typeSymbols;
}
ITypeSymbol? type = ResolveType(objectArg.Value)?.WithNullableAnnotation(NullableAnnotation.None);
- INamedTypeSymbol? namedType;
- if ((namedType = type as INamedTypeSymbol) is null ||
- namedType.SpecialType == SpecialType.System_Object ||
- namedType.SpecialType == SpecialType.System_Void ||
- // Binding to root-level struct is a no-op.
- namedType.IsValueType)
+ if (!IsValidRootConfigType(overload, type, binderOperation.Location))
{
return;
}
- AddRootConfigType(methodGroup: BinderMethodSpecifier.Bind, overload, namedType, binderOperation.Location);
+ if (type.IsValueType)
+ {
+ _context.ReportDiagnostic(Diagnostic.Create(Diagnostics.ValueTypesInvalidForBind, binderOperation.Location, type));
+ return;
+ }
+
+ AddRootConfigType(methodGroup: BinderMethodSpecifier.Bind, overload, type, binderOperation.Location);
static ITypeSymbol? ResolveType(IOperation conversionOperation) =>
conversionOperation switch
}
BinderMethodSpecifier overload = BinderMethodSpecifier.None;
- INamedTypeSymbol? namedType;
+ ITypeSymbol? type;
if (targetMethod.IsGenericMethod)
{
return;
}
- namedType = targetMethod.TypeArguments[0].WithNullableAnnotation(NullableAnnotation.None) as INamedTypeSymbol;
+ type = targetMethod.TypeArguments[0].WithNullableAnnotation(NullableAnnotation.None);
if (paramLength is 1)
{
else
{
ITypeOfOperation? typeOfOperation = operation.Arguments[1].ChildOperations.FirstOrDefault() as ITypeOfOperation;
- namedType = typeOfOperation?.TypeOperand as INamedTypeSymbol;
+ type = typeOfOperation?.TypeOperand;
if (paramLength is 2)
{
}
}
- if (overload is BinderMethodSpecifier.None ||
- namedType is null ||
- namedType.SpecialType == SpecialType.System_Object ||
- namedType.SpecialType == SpecialType.System_Void)
+ if (!IsValidRootConfigType(overload, type, binderOperation.Location))
{
return;
}
- AddRootConfigType(methodGroup: BinderMethodSpecifier.Get, overload, namedType, binderOperation.Location);
+ AddRootConfigType(methodGroup: BinderMethodSpecifier.Get, overload, type, binderOperation.Location);
}
private void ProcessGetValueCall(BinderInvocationOperation binderOperation)
}
}
- if (overload is BinderMethodSpecifier.None ||
- type is null ||
- type.SpecialType == SpecialType.System_Object ||
- type.SpecialType == SpecialType.System_Void)
+ if (!IsValidRootConfigType(overload, type, binderOperation.Location))
{
return;
}
- ITypeSymbol effectiveType = IsNullable(type, out ITypeSymbol? underlyingType) ? underlyingType : type;
+ ITypeSymbol effectiveType = (IsNullable(type, out ITypeSymbol? underlyingType) ? underlyingType : type)!;
if (IsParsableFromString(effectiveType, out _))
{
AddRootConfigType(methodGroup: BinderMethodSpecifier.GetValue, overload, type, binderOperation.Location);
SymbolEqualityComparer.Default.Equals(_typeSymbols.IConfiguration, @params[1].Type))
{
ITypeSymbol? type = targetMethod.TypeArguments[0].WithNullableAnnotation(NullableAnnotation.None);
- if (type is not INamedTypeSymbol namedType ||
- namedType.SpecialType == SpecialType.System_Object)
+
+ if (!IsValidRootConfigType(BinderMethodSpecifier.Configure, type, binderOperation.Location))
{
return;
}
- AddRootConfigType(methodGroup: BinderMethodSpecifier.Configure, overload: BinderMethodSpecifier.Configure, namedType, binderOperation.Location);
+ AddRootConfigType(methodGroup: BinderMethodSpecifier.Configure, overload: BinderMethodSpecifier.Configure, type, binderOperation.Location);
}
}
- private void AddRootConfigType(BinderMethodSpecifier methodGroup, BinderMethodSpecifier overload, ITypeSymbol type, Location? location)
+ private bool IsValidRootConfigType(BinderMethodSpecifier overload, ITypeSymbol? type, Location? location)
{
- if (type is INamedTypeSymbol namedType && ContainsGenericParameters(namedType))
+ if (overload is BinderMethodSpecifier.None)
{
- return;
+ return false;
+ }
+
+ if (type is null ||
+ type.SpecialType is SpecialType.System_Object or SpecialType.System_Void ||
+ type.TypeKind is TypeKind.TypeParameter or TypeKind.Pointer or TypeKind.Error ||
+ type.IsRefLikeType ||
+ ContainsGenericParameters(type))
+ {
+ _context.ReportDiagnostic(Diagnostic.Create(Diagnostics.CouldNotDetermineTypeInfo, location));
+ return false;
}
+ return true;
+ }
+
+ private void AddRootConfigType(BinderMethodSpecifier methodGroup, BinderMethodSpecifier overload, ITypeSymbol type, Location? location)
+ {
if (GetOrCreateTypeSpec(type, location) is TypeSpec spec)
{
RegisterConfigType(spec, overload);
if (IsNullable(type, out ITypeSymbol? underlyingType))
{
- spec = TryGetTypeSpec(underlyingType, ParserDiagnostics.NullableUnderlyingTypeNotSupported, out TypeSpec? underlyingTypeSpec)
+ spec = TryGetTypeSpec(underlyingType, Diagnostics.NullableUnderlyingTypeNotSupported, out TypeSpec? underlyingTypeSpec)
? new NullableSpec(type) { Location = location, UnderlyingType = underlyingTypeSpec }
: null;
}
if (spec is null)
{
- ReportUnsupportedType(type, ParserDiagnostics.TypeNotSupported, location);
+ ReportUnsupportedType(type, Diagnostics.TypeNotSupported, location);
return null;
}
private EnumerableSpec? CreateArraySpec(IArrayTypeSymbol arrayType, Location? location)
{
- if (!TryGetTypeSpec(arrayType.ElementType, ParserDiagnostics.ElementTypeNotSupported, out TypeSpec elementSpec))
+ if (!TryGetTypeSpec(arrayType.ElementType, Diagnostics.ElementTypeNotSupported, out TypeSpec elementSpec))
{
return null;
}
if (arrayType.Rank > 1)
{
- ReportUnsupportedType(arrayType, ParserDiagnostics.MultiDimArraysNotSupported, location);
+ ReportUnsupportedType(arrayType, Diagnostics.MultiDimArraysNotSupported, location);
return false;
}
private DictionarySpec CreateDictionarySpec(INamedTypeSymbol type, Location? location, ITypeSymbol keyType, ITypeSymbol elementType)
{
- if (!TryGetTypeSpec(keyType, ParserDiagnostics.DictionaryKeyNotSupported, out TypeSpec keySpec) ||
- !TryGetTypeSpec(elementType, ParserDiagnostics.ElementTypeNotSupported, out TypeSpec elementSpec))
+ if (!TryGetTypeSpec(keyType, Diagnostics.DictionaryKeyNotSupported, out TypeSpec keySpec) ||
+ !TryGetTypeSpec(elementType, Diagnostics.ElementTypeNotSupported, out TypeSpec elementSpec))
{
return null;
}
if (keySpec.SpecKind != TypeSpecKind.ParsableFromString)
{
- ReportUnsupportedType(type, ParserDiagnostics.DictionaryKeyNotSupported, location);
+ ReportUnsupportedType(type, Diagnostics.DictionaryKeyNotSupported, location);
return null;
}
}
else
{
- ReportUnsupportedType(type, ParserDiagnostics.CollectionNotSupported, location);
+ ReportUnsupportedType(type, Diagnostics.CollectionNotSupported, location);
return null;
}
}
}
else
{
- ReportUnsupportedType(type, ParserDiagnostics.CollectionNotSupported, location);
+ ReportUnsupportedType(type, Diagnostics.CollectionNotSupported, location);
return null;
}
private EnumerableSpec? CreateEnumerableSpec(INamedTypeSymbol type, Location? location)
{
if (!TryGetElementType(type, out ITypeSymbol? elementType) ||
- !TryGetTypeSpec(elementType, ParserDiagnostics.ElementTypeNotSupported, out TypeSpec elementSpec))
+ !TryGetTypeSpec(elementType, Diagnostics.ElementTypeNotSupported, out TypeSpec elementSpec))
{
return null;
}
}
else
{
- ReportUnsupportedType(type, ParserDiagnostics.CollectionNotSupported, location);
+ ReportUnsupportedType(type, Diagnostics.CollectionNotSupported, location);
return null;
}
}
}
else
{
- ReportUnsupportedType(type, ParserDiagnostics.CollectionNotSupported, location);
+ ReportUnsupportedType(type, Diagnostics.CollectionNotSupported, location);
return null;
}
bool hasPublicParameterlessCtor = type.IsValueType || parameterlessCtor is not null;
if (!hasPublicParameterlessCtor && hasMultipleParameterizedCtors)
{
- diagnosticDescriptor = ParserDiagnostics.MultipleParameterizedConstructors;
- objectSpec.InitExceptionMessage = string.Format(ExceptionMessages.MultipleParameterizedConstructors, typeName);
+ diagnosticDescriptor = Diagnostics.MultipleParameterizedConstructors;
+ objectSpec.InitExceptionMessage = string.Format(Emitter.ExceptionMessages.MultipleParameterizedConstructors, typeName);
}
ctor = type.IsValueType
if (ctor is null)
{
- diagnosticDescriptor = ParserDiagnostics.MissingPublicInstanceConstructor;
- objectSpec.InitExceptionMessage = string.Format(ExceptionMessages.MissingPublicInstanceConstructor, typeName);
+ diagnosticDescriptor = Diagnostics.MissingPublicInstanceConstructor;
+ objectSpec.InitExceptionMessage = string.Format(Emitter.ExceptionMessages.MissingPublicInstanceConstructor, typeName);
}
if (diagnosticDescriptor is not null)
TypeSpec? propertyTypeSpec = GetOrCreateTypeSpec(property.Type);
if (propertyTypeSpec is null)
{
- _context.ReportDiagnostic(Diagnostic.Create(ParserDiagnostics.PropertyNotSupported, location, new string[] { propertyName, type.ToDisplayString() }));
+ _context.ReportDiagnostic(Diagnostic.Create(Diagnostics.PropertyNotSupported, location, new string[] { propertyName, type.ToDisplayString() }));
}
else
{
if (invalidParameters.Count > 0)
{
- objectSpec.InitExceptionMessage = string.Format(ExceptionMessages.CannotBindToConstructorParameter, typeName, FormatParams(invalidParameters));
+ objectSpec.InitExceptionMessage = string.Format(Emitter.ExceptionMessages.CannotBindToConstructorParameter, typeName, FormatParams(invalidParameters));
}
else if (missingParameters.Count > 0)
{
}
else
{
- objectSpec.InitExceptionMessage = string.Format(ExceptionMessages.ConstructorParametersDoNotMatchProperties, typeName, FormatParams(missingParameters));
+ objectSpec.InitExceptionMessage = string.Format(Emitter.ExceptionMessages.ConstructorParametersDoNotMatchProperties, typeName, FormatParams(missingParameters));
}
}
return SymbolEqualityComparer.Default.Equals(type, @interface);
}
- public static bool ContainsGenericParameters(INamedTypeSymbol type)
+ public static bool ContainsGenericParameters(ITypeSymbol type)
{
- if (!type.IsGenericType)
+ if (type is not INamedTypeSymbol { IsGenericType: true } genericType)
{
return false;
}
- foreach (ITypeSymbol typeArg in type.TypeArguments)
+ foreach (ITypeSymbol typeArg in genericType.TypeArguments)
{
- if (typeArg.TypeKind == TypeKind.TypeParameter)
+ if (typeArg.TypeKind is TypeKind.TypeParameter or TypeKind.Error ||
+ ContainsGenericParameters(typeArg))
{
return true;
}
if (compilationData?.LanguageVersionIsSupported != true)
{
- context.ReportDiagnostic(Diagnostic.Create(ParserDiagnostics.LanguageVersionNotSupported, location: null));
+ context.ReportDiagnostic(Diagnostic.Create(Parser.Diagnostics.LanguageVersionNotSupported, location: null));
return;
}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
+{
+ public sealed partial class ConfigurationBindingGenerator
+ {
+ private sealed partial class Emitter
+ {
+ // Runtime exception messages; not localized so we keep them in source.
+ internal static class ExceptionMessages
+ {
+ public const string CannotBindToConstructorParameter = "Cannot create instance of type '{0}' because one or more parameters cannot be bound to. Constructor parameters cannot be declared as in, out, or ref. Invalid parameters are: '{1}'";
+ public const string CannotSpecifyBindNonPublicProperties = "The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.";
+ public const string ConstructorParametersDoNotMatchProperties = "Cannot create instance of type '{0}' because one or more parameters cannot be bound to. Constructor parameters must have corresponding properties. Fields are not supported. Missing properties are: '{1}'";
+ public const string FailedBinding = "Failed to convert configuration value at '{0}' to type '{1}'.";
+ public const string MissingConfig = "'{0}' was set on the provided {1}, but the following properties were not found on the instance of {2}: {3}";
+ public const string MissingPublicInstanceConstructor = "Cannot create instance of type '{0}' because it is missing a public instance constructor.";
+ public const string MultipleParameterizedConstructors = "Cannot create instance of type '{0}' because it has multiple public parameterized constructors.";
+ public const string ParameterHasNoMatchingConfig = "Cannot create instance of type '{0}' because parameter '{1}' has no matching config. Each parameter in the constructor that does not have a default value must have a corresponding config entry.";
+ public const string TypeNotDetectedAsInput = "Unable to bind to type '{0}': generator did not detect the type as input.";
+ }
+ }
+ }
+}
+++ /dev/null
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
-{
- // Runtime exception messages; not localized so we keep them in source.
- internal static class ExceptionMessages
- {
- public const string CannotBindToConstructorParameter = "Cannot create instance of type '{0}' because one or more parameters cannot be bound to. Constructor parameters cannot be declared as in, out, or ref. Invalid parameters are: '{1}'";
- public const string CannotSpecifyBindNonPublicProperties = "The configuration binding source generator does not support 'BinderOptions.BindNonPublicProperties'.";
- public const string ConstructorParametersDoNotMatchProperties = "Cannot create instance of type '{0}' because one or more parameters cannot be bound to. Constructor parameters must have corresponding properties. Fields are not supported. Missing properties are: '{1}'";
- public const string FailedBinding = "Failed to convert configuration value at '{0}' to type '{1}'.";
- public const string MissingConfig = "'{0}' was set on the provided {1}, but the following properties were not found on the instance of {2}: {3}";
- public const string MissingPublicInstanceConstructor = "Cannot create instance of type '{0}' because it is missing a public instance constructor.";
- public const string MultipleParameterizedConstructors = "Cannot create instance of type '{0}' because it has multiple public parameterized constructors.";
- public const string ParameterBeingBoundToIsUnnamed = "Cannot create instance of type '{0}' because one or more parameters are unnamed.";
- public const string ParameterHasNoMatchingConfig = "Cannot create instance of type '{0}' because parameter '{1}' has no matching config. Each parameter in the constructor that does not have a default value must have a corresponding config entry.";
- public const string TypeNotDetectedAsInput = "Unable to bind to type '{0}': generator did not detect the type as input.";
- public const string TypeNotSupportedAsInput = "Unable to bind to type '{0}': generator does not support this type as input to this method.";
- }
-}
--- /dev/null
+// 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 Microsoft.CodeAnalysis;
+
+namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
+{
+ public sealed partial class ConfigurationBindingGenerator
+ {
+ private sealed partial class Parser
+ {
+ internal static class Diagnostics
+ {
+ public static DiagnosticDescriptor TypeNotSupported { get; } = CreateTypeNotSupportedDescriptor(nameof(SR.TypeNotSupported));
+ public static DiagnosticDescriptor MissingPublicInstanceConstructor { get; } = CreateTypeNotSupportedDescriptor(nameof(SR.MissingPublicInstanceConstructor));
+ public static DiagnosticDescriptor CollectionNotSupported { get; } = CreateTypeNotSupportedDescriptor(nameof(SR.CollectionNotSupported));
+ public static DiagnosticDescriptor DictionaryKeyNotSupported { get; } = CreateTypeNotSupportedDescriptor(nameof(SR.DictionaryKeyNotSupported));
+ public static DiagnosticDescriptor ElementTypeNotSupported { get; } = CreateTypeNotSupportedDescriptor(nameof(SR.ElementTypeNotSupported));
+ public static DiagnosticDescriptor MultipleParameterizedConstructors { get; } = CreateTypeNotSupportedDescriptor(nameof(SR.MultipleParameterizedConstructors));
+ public static DiagnosticDescriptor MultiDimArraysNotSupported { get; } = CreateTypeNotSupportedDescriptor(nameof(SR.MultiDimArraysNotSupported));
+ public static DiagnosticDescriptor NullableUnderlyingTypeNotSupported { get; } = CreateTypeNotSupportedDescriptor(nameof(SR.NullableUnderlyingTypeNotSupported));
+
+ public static DiagnosticDescriptor PropertyNotSupported { get; } = new DiagnosticDescriptor(
+ id: "SYSLIB1101",
+ title: new LocalizableResourceString(nameof(SR.PropertyNotSupportedTitle), SR.ResourceManager, typeof(FxResources.Microsoft.Extensions.Configuration.Binder.SourceGeneration.SR)),
+ messageFormat: new LocalizableResourceString(nameof(SR.PropertyNotSupportedMessageFormat), SR.ResourceManager, typeof(FxResources.Microsoft.Extensions.Configuration.Binder.SourceGeneration.SR)),
+ category: ProjectName,
+ defaultSeverity: DiagnosticSeverity.Warning,
+ isEnabledByDefault: true);
+
+ public static DiagnosticDescriptor LanguageVersionNotSupported { get; } = new DiagnosticDescriptor(
+ id: "SYSLIB1102",
+ title: new LocalizableResourceString(nameof(SR.LanguageVersionIsNotSupportedTitle), SR.ResourceManager, typeof(FxResources.Microsoft.Extensions.Configuration.Binder.SourceGeneration.SR)),
+ messageFormat: new LocalizableResourceString(nameof(SR.Language_VersionIsNotSupportedMessageFormat), SR.ResourceManager, typeof(FxResources.Microsoft.Extensions.Configuration.Binder.SourceGeneration.SR)),
+ category: ProjectName,
+ defaultSeverity: DiagnosticSeverity.Error,
+ isEnabledByDefault: true);
+
+ public static DiagnosticDescriptor ValueTypesInvalidForBind { get; } = new DiagnosticDescriptor(
+ id: "SYSLIB1103",
+ title: new LocalizableResourceString(nameof(SR.ValueTypesInvalidForBindTitle), SR.ResourceManager, typeof(FxResources.Microsoft.Extensions.Configuration.Binder.SourceGeneration.SR)),
+ messageFormat: new LocalizableResourceString(nameof(SR.ValueTypesInvalidForBindMessageFormat), SR.ResourceManager, typeof(FxResources.Microsoft.Extensions.Configuration.Binder.SourceGeneration.SR)),
+ category: ProjectName,
+ defaultSeverity: DiagnosticSeverity.Warning,
+ isEnabledByDefault: true);
+
+ public static DiagnosticDescriptor CouldNotDetermineTypeInfo { get; } = new DiagnosticDescriptor(
+ id: "SYSLIB1104",
+ title: new LocalizableResourceString(nameof(SR.CouldNotDetermineTypeInfoTitle), SR.ResourceManager, typeof(FxResources.Microsoft.Extensions.Configuration.Binder.SourceGeneration.SR)),
+ messageFormat: new LocalizableResourceString(nameof(SR.CouldNotDetermineTypeInfoMessageFormat), SR.ResourceManager, typeof(FxResources.Microsoft.Extensions.Configuration.Binder.SourceGeneration.SR)),
+ category: ProjectName,
+ defaultSeverity: DiagnosticSeverity.Warning,
+ isEnabledByDefault: true);
+
+ private static DiagnosticDescriptor CreateTypeNotSupportedDescriptor(string nameofLocalizableMessageFormat) =>
+ new DiagnosticDescriptor(
+ id: "SYSLIB1100",
+ title: new LocalizableResourceString(nameof(SR.TypeNotSupportedTitle), SR.ResourceManager, typeof(FxResources.Microsoft.Extensions.Configuration.Binder.SourceGeneration.SR)),
+ messageFormat: new LocalizableResourceString(nameofLocalizableMessageFormat, SR.ResourceManager, typeof(FxResources.Microsoft.Extensions.Configuration.Binder.SourceGeneration.SR)),
+ category: ProjectName,
+ defaultSeverity: DiagnosticSeverity.Warning,
+ isEnabledByDefault: true);
+ }
+ }
+ }
+}
+++ /dev/null
-// 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 Microsoft.CodeAnalysis;
-
-namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration
-{
- internal static class ParserDiagnostics
- {
- public static DiagnosticDescriptor TypeNotSupported { get; } = CreateTypeNotSupportedDescriptor(nameof(SR.TypeNotSupported));
- public static DiagnosticDescriptor MissingPublicInstanceConstructor { get; } = CreateTypeNotSupportedDescriptor(nameof(SR.MissingPublicInstanceConstructor));
- public static DiagnosticDescriptor CollectionNotSupported { get; } = CreateTypeNotSupportedDescriptor(nameof(SR.CollectionNotSupported));
- public static DiagnosticDescriptor DictionaryKeyNotSupported { get; } = CreateTypeNotSupportedDescriptor(nameof(SR.DictionaryKeyNotSupported));
- public static DiagnosticDescriptor ElementTypeNotSupported { get; } = CreateTypeNotSupportedDescriptor(nameof(SR.ElementTypeNotSupported));
- public static DiagnosticDescriptor MultipleParameterizedConstructors { get; } = CreateTypeNotSupportedDescriptor(nameof(SR.MultipleParameterizedConstructors));
- public static DiagnosticDescriptor MultiDimArraysNotSupported { get; } = CreateTypeNotSupportedDescriptor(nameof(SR.MultiDimArraysNotSupported));
- public static DiagnosticDescriptor NullableUnderlyingTypeNotSupported { get; } = CreateTypeNotSupportedDescriptor(nameof(SR.NullableUnderlyingTypeNotSupported));
-
- public static DiagnosticDescriptor PropertyNotSupported { get; } = new DiagnosticDescriptor(
- id: "SYSLIB1101",
- title: new LocalizableResourceString(nameof(SR.PropertyNotSupportedTitle), SR.ResourceManager, typeof(FxResources.Microsoft.Extensions.Configuration.Binder.SourceGeneration.SR)),
- messageFormat: new LocalizableResourceString(nameof(SR.PropertyNotSupportedMessageFormat), SR.ResourceManager, typeof(FxResources.Microsoft.Extensions.Configuration.Binder.SourceGeneration.SR)),
- category: ConfigurationBindingGenerator.ProjectName,
- defaultSeverity: DiagnosticSeverity.Warning,
- isEnabledByDefault: true);
-
- public static DiagnosticDescriptor LanguageVersionNotSupported { get; } = new DiagnosticDescriptor(
- id: "SYSLIB1102",
- title: new LocalizableResourceString(nameof(SR.LanguageVersionIsNotSupportedTitle), SR.ResourceManager, typeof(FxResources.Microsoft.Extensions.Configuration.Binder.SourceGeneration.SR)),
- messageFormat: new LocalizableResourceString(nameof(SR.Language_VersionIsNotSupportedMessageFormat), SR.ResourceManager, typeof(FxResources.Microsoft.Extensions.Configuration.Binder.SourceGeneration.SR)),
- category: ConfigurationBindingGenerator.ProjectName,
- defaultSeverity: DiagnosticSeverity.Error,
- isEnabledByDefault: true);
-
- private static DiagnosticDescriptor CreateTypeNotSupportedDescriptor(string nameofLocalizableMessageFormat) =>
- new DiagnosticDescriptor(
- id: "SYSLIB1100",
- title: new LocalizableResourceString(nameof(SR.TypeNotSupportedTitle), SR.ResourceManager, typeof(FxResources.Microsoft.Extensions.Configuration.Binder.SourceGeneration.SR)),
- messageFormat: new LocalizableResourceString(nameofLocalizableMessageFormat, SR.ResourceManager, typeof(FxResources.Microsoft.Extensions.Configuration.Binder.SourceGeneration.SR)),
- category: ConfigurationBindingGenerator.ProjectName,
- defaultSeverity: DiagnosticSeverity.Warning,
- isEnabledByDefault: true);
- }
-}
<Compile Include="ConfigurationBindingGenerator.cs" />
<Compile Include="ConfigurationBindingGenerator.Emitter.cs" />
<Compile Include="ConfigurationBindingGenerator.Parser.cs" />
+ <Compile Include="Helpers\Emitter.ExceptionMessages.cs" />
<Compile Include="Helpers\Emitter.Helpers.cs" />
- <Compile Include="Helpers\ExceptionMessages.cs" />
- <Compile Include="Helpers\KnownTypeSymbols.cs" />
- <Compile Include="Helpers\ParserDiagnostics.cs" />
+ <Compile Include="Helpers\Parser.Diagnostics.cs" />
<Compile Include="Helpers\SourceWriter.cs" />
<Compile Include="Model\BinderInvocationOperation.cs" />
<Compile Include="Model\BinderMethodSpecifier.cs" />
<Compile Include="Model\CollectionSpec.cs" />
<Compile Include="Model\ConfigurationSectionSpec.cs" />
<Compile Include="Model\InitializationStrategy.cs" />
+ <Compile Include="Model\KnownTypeSymbols.cs" />
<Compile Include="Model\NullableSpec.cs" />
<Compile Include="Model\ObjectSpec.cs" />
<Compile Include="Model\ParameterSpec.cs" />
<data name="CollectionNotSupported" xml:space="preserve">
<value>The collection type is not supported: '{0}'.</value>
</data>
+ <data name="CouldNotDetermineTypeInfoMessageFormat" xml:space="preserve">
+ <value>Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects.</value>
+ </data>
+ <data name="CouldNotDetermineTypeInfoTitle" xml:space="preserve">
+ <value>The target type for a binder call could not be determined</value>
+ </data>
<data name="DictionaryKeyNotSupported" xml:space="preserve">
<value>The dictionary key type is not supported: '{0}'.</value>
</data>
<data name="TypeNotSupportedTitle" xml:space="preserve">
<value>Did not generate binding logic for a type</value>
</data>
+ <data name="ValueTypesInvalidForBindMessageFormat" xml:space="preserve">
+ <value>Binding logic was not generated for a binder call with target type '{0}'. Value types are invalid inputs to configuration 'Bind' methods.</value>
+ </data>
+ <data name="ValueTypesInvalidForBindTitle" xml:space="preserve">
+ <value>Value types are invalid inputs to configuration 'Bind' methods</value>
+ </data>
</root>
\ No newline at end of file
<target state="translated">Typ kolekce se nepodporuje: „{0}“.</target>
<note />
</trans-unit>
+ <trans-unit id="CouldNotDetermineTypeInfoMessageFormat">
+ <source>Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects.</source>
+ <target state="new">Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="CouldNotDetermineTypeInfoTitle">
+ <source>The target type for a binder call could not be determined</source>
+ <target state="new">The target type for a binder call could not be determined</target>
+ <note />
+ </trans-unit>
<trans-unit id="DictionaryKeyNotSupported">
<source>The dictionary key type is not supported: '{0}'.</source>
<target state="translated">Typ klíče slovníku se nepodporuje:„{0}“.</target>
<target state="translated">Negenerovala se logika vazby pro typ</target>
<note />
</trans-unit>
+ <trans-unit id="ValueTypesInvalidForBindMessageFormat">
+ <source>Binding logic was not generated for a binder call with target type '{0}'. Value types are invalid inputs to configuration 'Bind' methods.</source>
+ <target state="new">Binding logic was not generated for a binder call with target type '{0}'. Value types are invalid inputs to configuration 'Bind' methods.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="ValueTypesInvalidForBindTitle">
+ <source>Value types are invalid inputs to configuration 'Bind' methods</source>
+ <target state="new">Value types are invalid inputs to configuration 'Bind' methods</target>
+ <note />
+ </trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
<target state="translated">Der Sammlungstyp wird nicht unterstützt: "{0}".</target>
<note />
</trans-unit>
+ <trans-unit id="CouldNotDetermineTypeInfoMessageFormat">
+ <source>Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects.</source>
+ <target state="new">Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="CouldNotDetermineTypeInfoTitle">
+ <source>The target type for a binder call could not be determined</source>
+ <target state="new">The target type for a binder call could not be determined</target>
+ <note />
+ </trans-unit>
<trans-unit id="DictionaryKeyNotSupported">
<source>The dictionary key type is not supported: '{0}'.</source>
<target state="translated">Der Wörterbuchschlüsseltyp wird nicht unterstützt: "{0}".</target>
<target state="translated">Für einen Typ wurde keine Bindungslogik generiert</target>
<note />
</trans-unit>
+ <trans-unit id="ValueTypesInvalidForBindMessageFormat">
+ <source>Binding logic was not generated for a binder call with target type '{0}'. Value types are invalid inputs to configuration 'Bind' methods.</source>
+ <target state="new">Binding logic was not generated for a binder call with target type '{0}'. Value types are invalid inputs to configuration 'Bind' methods.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="ValueTypesInvalidForBindTitle">
+ <source>Value types are invalid inputs to configuration 'Bind' methods</source>
+ <target state="new">Value types are invalid inputs to configuration 'Bind' methods</target>
+ <note />
+ </trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
<target state="translated">No se admite el tipo de colección: "{0}".</target>
<note />
</trans-unit>
+ <trans-unit id="CouldNotDetermineTypeInfoMessageFormat">
+ <source>Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects.</source>
+ <target state="new">Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="CouldNotDetermineTypeInfoTitle">
+ <source>The target type for a binder call could not be determined</source>
+ <target state="new">The target type for a binder call could not be determined</target>
+ <note />
+ </trans-unit>
<trans-unit id="DictionaryKeyNotSupported">
<source>The dictionary key type is not supported: '{0}'.</source>
<target state="translated">No se admite el tipo de clave de diccionario: "{0}".</target>
<target state="translated">No se ha generado la lógica de enlace para un tipo.</target>
<note />
</trans-unit>
+ <trans-unit id="ValueTypesInvalidForBindMessageFormat">
+ <source>Binding logic was not generated for a binder call with target type '{0}'. Value types are invalid inputs to configuration 'Bind' methods.</source>
+ <target state="new">Binding logic was not generated for a binder call with target type '{0}'. Value types are invalid inputs to configuration 'Bind' methods.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="ValueTypesInvalidForBindTitle">
+ <source>Value types are invalid inputs to configuration 'Bind' methods</source>
+ <target state="new">Value types are invalid inputs to configuration 'Bind' methods</target>
+ <note />
+ </trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
<target state="translated">Le type de collection n‘est pas pris en charge : ‘{0}‘.</target>
<note />
</trans-unit>
+ <trans-unit id="CouldNotDetermineTypeInfoMessageFormat">
+ <source>Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects.</source>
+ <target state="new">Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="CouldNotDetermineTypeInfoTitle">
+ <source>The target type for a binder call could not be determined</source>
+ <target state="new">The target type for a binder call could not be determined</target>
+ <note />
+ </trans-unit>
<trans-unit id="DictionaryKeyNotSupported">
<source>The dictionary key type is not supported: '{0}'.</source>
<target state="translated">Le type de clé du dictionnaire n’est pas pris en charge : ‘{0}‘.</target>
<target state="translated">La logique de liaison n’a pas été générée pour un type</target>
<note />
</trans-unit>
+ <trans-unit id="ValueTypesInvalidForBindMessageFormat">
+ <source>Binding logic was not generated for a binder call with target type '{0}'. Value types are invalid inputs to configuration 'Bind' methods.</source>
+ <target state="new">Binding logic was not generated for a binder call with target type '{0}'. Value types are invalid inputs to configuration 'Bind' methods.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="ValueTypesInvalidForBindTitle">
+ <source>Value types are invalid inputs to configuration 'Bind' methods</source>
+ <target state="new">Value types are invalid inputs to configuration 'Bind' methods</target>
+ <note />
+ </trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
<target state="translated">Il tipo di raccolta non è supportato: '{0}'.</target>
<note />
</trans-unit>
+ <trans-unit id="CouldNotDetermineTypeInfoMessageFormat">
+ <source>Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects.</source>
+ <target state="new">Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="CouldNotDetermineTypeInfoTitle">
+ <source>The target type for a binder call could not be determined</source>
+ <target state="new">The target type for a binder call could not be determined</target>
+ <note />
+ </trans-unit>
<trans-unit id="DictionaryKeyNotSupported">
<source>The dictionary key type is not supported: '{0}'.</source>
<target state="translated">Il tipo di chiave del dizionario non è supportato: '{0}'.</target>
<target state="translated">Non è stata generata la logica di binding per un tipo.</target>
<note />
</trans-unit>
+ <trans-unit id="ValueTypesInvalidForBindMessageFormat">
+ <source>Binding logic was not generated for a binder call with target type '{0}'. Value types are invalid inputs to configuration 'Bind' methods.</source>
+ <target state="new">Binding logic was not generated for a binder call with target type '{0}'. Value types are invalid inputs to configuration 'Bind' methods.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="ValueTypesInvalidForBindTitle">
+ <source>Value types are invalid inputs to configuration 'Bind' methods</source>
+ <target state="new">Value types are invalid inputs to configuration 'Bind' methods</target>
+ <note />
+ </trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
<target state="translated">コレクション型はサポートされていません: '{0}'。</target>
<note />
</trans-unit>
+ <trans-unit id="CouldNotDetermineTypeInfoMessageFormat">
+ <source>Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects.</source>
+ <target state="new">Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="CouldNotDetermineTypeInfoTitle">
+ <source>The target type for a binder call could not be determined</source>
+ <target state="new">The target type for a binder call could not be determined</target>
+ <note />
+ </trans-unit>
<trans-unit id="DictionaryKeyNotSupported">
<source>The dictionary key type is not supported: '{0}'.</source>
<target state="translated">辞書キー型はサポートされていません: '{0}'。</target>
<target state="translated">型のバインディング ロジックを生成しませんでした</target>
<note />
</trans-unit>
+ <trans-unit id="ValueTypesInvalidForBindMessageFormat">
+ <source>Binding logic was not generated for a binder call with target type '{0}'. Value types are invalid inputs to configuration 'Bind' methods.</source>
+ <target state="new">Binding logic was not generated for a binder call with target type '{0}'. Value types are invalid inputs to configuration 'Bind' methods.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="ValueTypesInvalidForBindTitle">
+ <source>Value types are invalid inputs to configuration 'Bind' methods</source>
+ <target state="new">Value types are invalid inputs to configuration 'Bind' methods</target>
+ <note />
+ </trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
<target state="translated">컬렉션 유형이 지원되지 않습니다: '{0}'.</target>
<note />
</trans-unit>
+ <trans-unit id="CouldNotDetermineTypeInfoMessageFormat">
+ <source>Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects.</source>
+ <target state="new">Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="CouldNotDetermineTypeInfoTitle">
+ <source>The target type for a binder call could not be determined</source>
+ <target state="new">The target type for a binder call could not be determined</target>
+ <note />
+ </trans-unit>
<trans-unit id="DictionaryKeyNotSupported">
<source>The dictionary key type is not supported: '{0}'.</source>
<target state="translated">사전 키 유형이 지원되지 않습니다: '{0}'.</target>
<target state="translated">형식에 대한 바인딩 논리를 생성하지 않았습니다.</target>
<note />
</trans-unit>
+ <trans-unit id="ValueTypesInvalidForBindMessageFormat">
+ <source>Binding logic was not generated for a binder call with target type '{0}'. Value types are invalid inputs to configuration 'Bind' methods.</source>
+ <target state="new">Binding logic was not generated for a binder call with target type '{0}'. Value types are invalid inputs to configuration 'Bind' methods.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="ValueTypesInvalidForBindTitle">
+ <source>Value types are invalid inputs to configuration 'Bind' methods</source>
+ <target state="new">Value types are invalid inputs to configuration 'Bind' methods</target>
+ <note />
+ </trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
<target state="translated">Typ kolekcji nie jest obsługiwany: „{0}”.</target>
<note />
</trans-unit>
+ <trans-unit id="CouldNotDetermineTypeInfoMessageFormat">
+ <source>Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects.</source>
+ <target state="new">Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="CouldNotDetermineTypeInfoTitle">
+ <source>The target type for a binder call could not be determined</source>
+ <target state="new">The target type for a binder call could not be determined</target>
+ <note />
+ </trans-unit>
<trans-unit id="DictionaryKeyNotSupported">
<source>The dictionary key type is not supported: '{0}'.</source>
<target state="translated">Typ klucza słownika nie jest obsługiwany: „{0}”.</target>
<target state="translated">Nie wygenerowano logiki powiązania dla typu</target>
<note />
</trans-unit>
+ <trans-unit id="ValueTypesInvalidForBindMessageFormat">
+ <source>Binding logic was not generated for a binder call with target type '{0}'. Value types are invalid inputs to configuration 'Bind' methods.</source>
+ <target state="new">Binding logic was not generated for a binder call with target type '{0}'. Value types are invalid inputs to configuration 'Bind' methods.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="ValueTypesInvalidForBindTitle">
+ <source>Value types are invalid inputs to configuration 'Bind' methods</source>
+ <target state="new">Value types are invalid inputs to configuration 'Bind' methods</target>
+ <note />
+ </trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
<target state="translated">O tipo de coleção não é compatível: '{0}'.</target>
<note />
</trans-unit>
+ <trans-unit id="CouldNotDetermineTypeInfoMessageFormat">
+ <source>Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects.</source>
+ <target state="new">Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="CouldNotDetermineTypeInfoTitle">
+ <source>The target type for a binder call could not be determined</source>
+ <target state="new">The target type for a binder call could not be determined</target>
+ <note />
+ </trans-unit>
<trans-unit id="DictionaryKeyNotSupported">
<source>The dictionary key type is not supported: '{0}'.</source>
<target state="translated">O tipo de chave do dicionário não é suportado: '{0}'.</target>
<target state="translated">Não gerou lógica de ligação para um tipo</target>
<note />
</trans-unit>
+ <trans-unit id="ValueTypesInvalidForBindMessageFormat">
+ <source>Binding logic was not generated for a binder call with target type '{0}'. Value types are invalid inputs to configuration 'Bind' methods.</source>
+ <target state="new">Binding logic was not generated for a binder call with target type '{0}'. Value types are invalid inputs to configuration 'Bind' methods.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="ValueTypesInvalidForBindTitle">
+ <source>Value types are invalid inputs to configuration 'Bind' methods</source>
+ <target state="new">Value types are invalid inputs to configuration 'Bind' methods</target>
+ <note />
+ </trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
<target state="translated">Тип коллекции не поддерживается: "{0}".</target>
<note />
</trans-unit>
+ <trans-unit id="CouldNotDetermineTypeInfoMessageFormat">
+ <source>Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects.</source>
+ <target state="new">Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="CouldNotDetermineTypeInfoTitle">
+ <source>The target type for a binder call could not be determined</source>
+ <target state="new">The target type for a binder call could not be determined</target>
+ <note />
+ </trans-unit>
<trans-unit id="DictionaryKeyNotSupported">
<source>The dictionary key type is not supported: '{0}'.</source>
<target state="translated">Тип ключа словаря не поддерживается: "{0}".</target>
<target state="translated">Не создана логика привязки для типа</target>
<note />
</trans-unit>
+ <trans-unit id="ValueTypesInvalidForBindMessageFormat">
+ <source>Binding logic was not generated for a binder call with target type '{0}'. Value types are invalid inputs to configuration 'Bind' methods.</source>
+ <target state="new">Binding logic was not generated for a binder call with target type '{0}'. Value types are invalid inputs to configuration 'Bind' methods.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="ValueTypesInvalidForBindTitle">
+ <source>Value types are invalid inputs to configuration 'Bind' methods</source>
+ <target state="new">Value types are invalid inputs to configuration 'Bind' methods</target>
+ <note />
+ </trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
<target state="translated">Koleksiyon türü desteklenmiyor: '{0}'.</target>
<note />
</trans-unit>
+ <trans-unit id="CouldNotDetermineTypeInfoMessageFormat">
+ <source>Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects.</source>
+ <target state="new">Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="CouldNotDetermineTypeInfoTitle">
+ <source>The target type for a binder call could not be determined</source>
+ <target state="new">The target type for a binder call could not be determined</target>
+ <note />
+ </trans-unit>
<trans-unit id="DictionaryKeyNotSupported">
<source>The dictionary key type is not supported: '{0}'.</source>
<target state="translated">Sözlük anahtarı türü desteklenmiyor: '{0}'.</target>
<target state="translated">Bir tür için bağlama mantığı oluşturulmadı</target>
<note />
</trans-unit>
+ <trans-unit id="ValueTypesInvalidForBindMessageFormat">
+ <source>Binding logic was not generated for a binder call with target type '{0}'. Value types are invalid inputs to configuration 'Bind' methods.</source>
+ <target state="new">Binding logic was not generated for a binder call with target type '{0}'. Value types are invalid inputs to configuration 'Bind' methods.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="ValueTypesInvalidForBindTitle">
+ <source>Value types are invalid inputs to configuration 'Bind' methods</source>
+ <target state="new">Value types are invalid inputs to configuration 'Bind' methods</target>
+ <note />
+ </trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
<target state="translated">不支持此集合类型 '{0}'。</target>
<note />
</trans-unit>
+ <trans-unit id="CouldNotDetermineTypeInfoMessageFormat">
+ <source>Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects.</source>
+ <target state="new">Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="CouldNotDetermineTypeInfoTitle">
+ <source>The target type for a binder call could not be determined</source>
+ <target state="new">The target type for a binder call could not be determined</target>
+ <note />
+ </trans-unit>
<trans-unit id="DictionaryKeyNotSupported">
<source>The dictionary key type is not supported: '{0}'.</source>
<target state="translated">不支持此字典密钥类型: '{0}'。</target>
<target state="translated">没有为类型生成绑定逻辑</target>
<note />
</trans-unit>
+ <trans-unit id="ValueTypesInvalidForBindMessageFormat">
+ <source>Binding logic was not generated for a binder call with target type '{0}'. Value types are invalid inputs to configuration 'Bind' methods.</source>
+ <target state="new">Binding logic was not generated for a binder call with target type '{0}'. Value types are invalid inputs to configuration 'Bind' methods.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="ValueTypesInvalidForBindTitle">
+ <source>Value types are invalid inputs to configuration 'Bind' methods</source>
+ <target state="new">Value types are invalid inputs to configuration 'Bind' methods</target>
+ <note />
+ </trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
<target state="translated">不支援集合類型: '{0}'。</target>
<note />
</trans-unit>
+ <trans-unit id="CouldNotDetermineTypeInfoMessageFormat">
+ <source>Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects.</source>
+ <target state="new">Binding logic was not generated for a binder call. Unsupported input patterns include generic calls and passing boxed objects.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="CouldNotDetermineTypeInfoTitle">
+ <source>The target type for a binder call could not be determined</source>
+ <target state="new">The target type for a binder call could not be determined</target>
+ <note />
+ </trans-unit>
<trans-unit id="DictionaryKeyNotSupported">
<source>The dictionary key type is not supported: '{0}'.</source>
<target state="translated">不支援字典索引鍵類型: '{0}'。</target>
<target state="translated">未產生類型的繫結邏輯</target>
<note />
</trans-unit>
+ <trans-unit id="ValueTypesInvalidForBindMessageFormat">
+ <source>Binding logic was not generated for a binder call with target type '{0}'. Value types are invalid inputs to configuration 'Bind' methods.</source>
+ <target state="new">Binding logic was not generated for a binder call with target type '{0}'. Value types are invalid inputs to configuration 'Bind' methods.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="ValueTypesInvalidForBindTitle">
+ <source>Value types are invalid inputs to configuration 'Bind' methods</source>
+ <target state="new">Value types are invalid inputs to configuration 'Bind' methods</target>
+ <note />
+ </trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
Assert.Equal("val_3", options[KeyUintEnum.ghi]);
}
- [ConditionalFact(typeof(TestHelpers), nameof(TestHelpers.NotSourceGenMode))] // Reflection fallback: generic type info not supported with source gen.
+ // Reflection fallback: generic type info not supported with source gen.
+ [ConditionalFact(typeof(TestHelpers), nameof(TestHelpers.NotSourceGenMode))]
public void GetSByteDictionary()
{
GetIntDictionaryT<sbyte>(0, 1, 2);
}
- [ConditionalFact(typeof(TestHelpers), nameof(TestHelpers.NotSourceGenMode))] // Reflection fallback: generic type info not supported with source gen.
+ // Reflection fallback: generic type info not supported with source gen.
+ [ConditionalFact(typeof(TestHelpers), nameof(TestHelpers.NotSourceGenMode))]
public void GetByteDictionary()
{
GetIntDictionaryT<byte>(0, 1, 2);
}
- [ConditionalFact(typeof(TestHelpers), nameof(TestHelpers.NotSourceGenMode))] // Reflection fallback: generic type info not supported with source gen.
+ // Reflection fallback: generic type info not supported with source gen.
+ [ConditionalFact(typeof(TestHelpers), nameof(TestHelpers.NotSourceGenMode))]
public void GetShortDictionary()
{
GetIntDictionaryT<short>(0, 1, 2);
}
- [ConditionalFact(typeof(TestHelpers), nameof(TestHelpers.NotSourceGenMode))] // Reflection fallback: generic type info not supported with source gen.
+ // Reflection fallback: generic type info not supported with source gen.
+ [ConditionalFact(typeof(TestHelpers), nameof(TestHelpers.NotSourceGenMode))]
public void GetUShortDictionary()
{
GetIntDictionaryT<ushort>(0, 1, 2);
}
- [ConditionalFact(typeof(TestHelpers), nameof(TestHelpers.NotSourceGenMode))] // Reflection fallback: generic type info not supported with source gen.
+ // Reflection fallback: generic type info not supported with source gen.
+ [ConditionalFact(typeof(TestHelpers), nameof(TestHelpers.NotSourceGenMode))]
public void GetIntDictionary()
{
GetIntDictionaryT<int>(0, 1, 2);
}
- [ConditionalFact(typeof(TestHelpers), nameof(TestHelpers.NotSourceGenMode))] // Reflection fallback: generic type info not supported with source gen.
+ // Reflection fallback: generic type info not supported with source gen.
+ [ConditionalFact(typeof(TestHelpers), nameof(TestHelpers.NotSourceGenMode))]
public void GetUIntDictionary()
{
GetIntDictionaryT<uint>(0, 1, 2);
}
- [ConditionalFact(typeof(TestHelpers), nameof(TestHelpers.NotSourceGenMode))] // Reflection fallback: generic type info not supported with source gen.
+ // Reflection fallback: generic type info not supported with source gen.
+ [ConditionalFact(typeof(TestHelpers), nameof(TestHelpers.NotSourceGenMode))]
public void GetLongDictionary()
{
GetIntDictionaryT<long>(0, 1, 2);
}
- [ConditionalFact(typeof(TestHelpers), nameof(TestHelpers.NotSourceGenMode))] // Reflection fallback: generic type info not supported with source gen.
+ // Reflection fallback: generic type info not supported with source gen.
+ [ConditionalFact(typeof(TestHelpers), nameof(TestHelpers.NotSourceGenMode))]
public void GetULongDictionary()
{
GetIntDictionaryT<ulong>(0, 1, 2);
public TimeOnly Prop22 { get; set; }
#endif
}
+
+ public class ClassWithParameterlessAndParameterizedCtor
+ {
+ public ClassWithParameterlessAndParameterizedCtor() => MyInt = 1;
+
+ public ClassWithParameterlessAndParameterizedCtor(int myInt) => MyInt = 10;
+
+ public int MyInt { get; }
+ }
+
+ public struct StructWithParameterlessAndParameterizedCtor
+ {
+ public StructWithParameterlessAndParameterizedCtor() => MyInt = 1;
+
+ public StructWithParameterlessAndParameterizedCtor(int myInt) => MyInt = 10;
+
+ public int MyInt { get; }
+ }
}
}
Assert.Equal(1, obj.MyInt);
}
- public class ClassWithParameterlessAndParameterizedCtor
- {
- public ClassWithParameterlessAndParameterizedCtor() => MyInt = 1;
-
- public ClassWithParameterlessAndParameterizedCtor(int myInt) => MyInt = 10;
-
- public int MyInt { get; }
- }
-
- public struct StructWithParameterlessAndParameterizedCtor
+ [Fact]
+ public void BindRootStructIsNoOp()
{
- public StructWithParameterlessAndParameterizedCtor() => MyInt = 1;
-
- public StructWithParameterlessAndParameterizedCtor(int myInt) => MyInt = 10;
+ var configuration = TestHelpers.GetConfigurationFromJsonString("""
+ {
+ "Int32": 9,
+ "Boolean": true,
+ }
+ """);
- public int MyInt { get; }
+ StructWithNestedStructs.DeeplyNested obj = new();
+ configuration.Bind(obj);
+ Assert.Equal(0, obj.Int32);
+ Assert.False(obj.Boolean);
}
}
}
[ActiveIssue("https://github.com/dotnet/runtime/issues/52062", TestPlatforms.Browser)]
public class ConfigurationBindingSourceGeneratorTests
{
+ private static class Diagnostics
+ {
+ public static (string Id, string Title) TypeNotSupported = ("SYSLIB1100", "Did not generate binding logic for a type");
+ public static (string Id, string Title) PropertyNotSupported = ("SYSLIB1101", "Did not generate binding logic for a property on a type");
+ public static (string Id, string Title) ValueTypesInvalidForBind = ("SYSLIB1103", "Value types are invalid inputs to configuration 'Bind' methods");
+ public static (string Id, string Title) CouldNotDetermineTypeInfo = ("SYSLIB1104", "The target type for a binder call could not be determined");
+ }
+
private const string BindCallSampleCode = @"
using System.Collections.Generic;
using Microsoft.Extensions.Configuration;
await VerifyAgainstBaselineUsingFile("TestCollectionsGen.generated.txt", testSourceCode, assessDiagnostics: (d) =>
{
Assert.Equal(6, d.Length);
- Test(d.Where(diagnostic => diagnostic.Id is "SYSLIB1100"), "Did not generate binding logic for a type");
- Test(d.Where(diagnostic => diagnostic.Id is "SYSLIB1101"), "Did not generate binding logic for a property on a type");
+ Test(d.Where(diagnostic => diagnostic.Id == Diagnostics.TypeNotSupported.Id), Diagnostics.TypeNotSupported.Title);
+ Test(d.Where(diagnostic => diagnostic.Id == Diagnostics.PropertyNotSupported.Id), Diagnostics.PropertyNotSupported.Title);
static void Test(IEnumerable<Diagnostic> d, string expectedTitle)
{
});
}
+ [Fact]
+ public async Task ValueTypesAreInvalidAsBindInputs()
+ {
+ string source = """
+ using System;
+ using System.Collections.Generic;
+ using Microsoft.Extensions.Configuration;
+
+ public class Program
+ {
+ public static void Main()
+ {
+ ConfigurationBuilder configurationBuilder = new();
+ IConfigurationRoot config = configurationBuilder.Build();
+
+ int myInt = 1
+ config.Bind(myInt);
+ int? myNInt = 2;
+ config.Bind(myNInt)
+
+ var myStruct = new MyStruct()
+ config.Bind(myStruct, options => { })
+ MyStruct? myNStruct = new();
+ config.Bind(myNStruct, options => { });
+
+ var myRecordStruct = new MyRecordStruct();
+ config.Bind("key", myRecordStruct);
+ MyRecordStruct? myNRecordStruct = new();
+ config.Bind("key", myNRecordStruct);
+
+ Memory<int> memory = new(new int[] {1, 2, 3});
+ config.Bind(memory);
+ }
+
+ public struct MyStruct { }
+ public record struct MyRecordStruct { }
+ }
+ """;
+
+ var (d, r) = await RunGenerator(source);
+ Assert.Empty(r);
+ Assert.Equal(7, d.Count());
+
+ foreach (Diagnostic diagnostic in d)
+ {
+ Assert.True(diagnostic.Id == Diagnostics.ValueTypesInvalidForBind.Id);
+ Assert.Contains(Diagnostics.ValueTypesInvalidForBind.Title, diagnostic.Descriptor.Title.ToString(CultureInfo.InvariantCulture));
+ Assert.Equal(DiagnosticSeverity.Warning, diagnostic.Severity);
+ Assert.NotNull(diagnostic.Location);
+ }
+ }
+
+ [Fact]
+ public async Task InvalidRootMethodInputTypes()
+ {
+ string source = """
+ using System.Collections.Generic;
+ using Microsoft.Extensions.Configuration;
+
+ public class Program
+ {
+ public static void Main()
+ {
+ ConfigurationBuilder configurationBuilder = new();
+ IConfigurationRoot config = configurationBuilder.Build();
+
+ config.GetValue(typeof(int*), "");
+ config.Get<Dictionary<string, T>>();
+ }
+
+ public struct MyStruct { }
+ public record struct MyRecordStruct { }
+ }
+ """;
+
+ var (d, r) = await RunGenerator(source);
+ Assert.Empty(r);
+ Assert.Equal(2, d.Count());
+
+ foreach (Diagnostic diagnostic in d)
+ {
+ Assert.True(diagnostic.Id == Diagnostics.CouldNotDetermineTypeInfo.Id);
+ Assert.Contains(Diagnostics.CouldNotDetermineTypeInfo.Title, diagnostic.Descriptor.Title.ToString(CultureInfo.InvariantCulture));
+ Assert.Equal(DiagnosticSeverity.Warning, diagnostic.Severity);
+ Assert.NotNull(diagnostic.Location);
+ }
+ }
+
+ [Fact]
+ public async Task CannotDetermineTypeInfo()
+ {
+ string source = """
+ using Microsoft.AspNetCore.Builder;
+ using Microsoft.Extensions.Configuration;
+ using Microsoft.Extensions.DependencyInjection;
+
+ public class Program
+ {
+ public static void Main()
+ {
+ ConfigurationBuilder configurationBuilder = new();
+ IConfiguration config = configurationBuilder.Build();
+
+ PerformGenericBinderCalls<MyClass>(config);
+ }
+
+ public static void PerformGenericBinderCalls<T>(IConfiguration config) where T : class
+ {
+ config.Get<T>();
+ config.Get<T>(binderOptions => { });
+ config.GetValue<T>("key");
+ config.GetValue<T>("key", default(T));
+
+ IConfigurationSection section = config.GetSection("MySection");
+ ServiceCollection services = new();
+ services.Configure<T>(section);
+ }
+
+ private void BindOptions(IConfiguration config, object? instance)
+ {
+ config.Bind(instance);
+ }
+
+ public class MyClass { }
+ }
+ """;
+
+ var (d, r) = await RunGenerator(source);
+ Assert.Empty(r);
+ Assert.Equal(5, d.Count());
+
+ foreach (Diagnostic diagnostic in d)
+ {
+ Assert.True(diagnostic.Id == Diagnostics.CouldNotDetermineTypeInfo.Id);
+ Assert.Contains(Diagnostics.CouldNotDetermineTypeInfo.Title, diagnostic.Descriptor.Title.ToString(CultureInfo.InvariantCulture));
+ Assert.Equal(DiagnosticSeverity.Warning, diagnostic.Severity);
+ Assert.NotNull(diagnostic.Location);
+ }
+ }
+
private async Task VerifyAgainstBaselineUsingFile(
string filename,
string testSourceCode,
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<EnableDefaultItems>true</EnableDefaultItems>
<DefineConstants>$(DefineConstants);BUILDING_SOURCE_GENERATOR_TESTS;ROSLYN4_0_OR_GREATER;ROSLYN4_4_OR_GREATER</DefineConstants>
- <!-- Type not supported; property on type not suppported. -->
- <NoWarn>SYSLIB1100,SYSLIB1101</NoWarn>
+ <!-- Type not supported; property on type not suppported; value types invalid for bind; generator could not parse target type -->
+ <NoWarn>SYSLIB1100,SYSLIB1101,SYSLIB1103,SYSLIB1104</NoWarn>
<!-- The SDK disables the configuration binding generator by default no matter how it was referenced, so we need to enable it here for testing. -->
<EnableConfigurationBindingGenerator>true</EnableConfigurationBindingGenerator>
</PropertyGroup>