diff --git a/api_list.include.md b/api_list.include.md index c8ca2f07..02f7218c 100644 --- a/api_list.include.md +++ b/api_list.include.md @@ -8,6 +8,11 @@ * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.byte.tryformat) +### Dictionary + + * `Boolean Remove(TKey, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2.remove) + + ### IEnumerable * `IEnumerable Chunk(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.chunk) @@ -54,11 +59,6 @@ * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.decimal.tryformat) -### Dictionary - - * `Boolean Remove(TKey, out TValue)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2.remove) - - ### Double * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.double.tryformat) diff --git a/readme.md b/readme.md index 7829e9e6..f9827642 100644 --- a/readme.md +++ b/readme.md @@ -363,6 +363,11 @@ The class `PolyfillExtensions` includes the following extension methods: * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.byte.tryformat) +### Dictionary + + * `Boolean Remove(TKey, TValue&)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2.remove) + + ### IEnumerable * `IEnumerable Chunk(Int32)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.chunk) @@ -409,11 +414,6 @@ The class `PolyfillExtensions` includes the following extension methods: * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.decimal.tryformat) -### Dictionary - - * `Boolean Remove(TKey, out TValue)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2.remove) - - ### Double * `Boolean TryFormat(Span, Int32&, ReadOnlySpan, IFormatProvider)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.double.tryformat) diff --git a/src/Polyfill/Nullability/NullabilityInfoContext.cs b/src/Polyfill/Nullability/NullabilityInfoContext.cs index 18964394..fc2dbe3e 100644 --- a/src/Polyfill/Nullability/NullabilityInfoContext.cs +++ b/src/Polyfill/Nullability/NullabilityInfoContext.cs @@ -97,35 +97,47 @@ public NullabilityInfo Create(ParameterInfo parameterInfo) private void CheckParameterMetadataType(ParameterInfo parameter, NullabilityInfo nullability) { - if (parameter.Member is MethodInfo method) + ParameterInfo? metaParameter; + MemberInfo metaMember; + + switch (parameter.Member) { - MethodInfo metaMethod = GetMethodMetadataDefinition(method); - ParameterInfo? metaParameter = null; - if (string.IsNullOrEmpty(parameter.Name)) - { - metaParameter = metaMethod.ReturnParameter; - } - else - { - ParameterInfo[] parameters = metaMethod.GetParameters(); - for (int i = 0; i < parameters.Length; i++) - { - if (parameter.Position == i && - parameter.Name == parameters[i].Name) - { - metaParameter = parameters[i]; - break; - } - } - } + case ConstructorInfo ctor: + var metaCtor = (ConstructorInfo)GetMemberMetadataDefinition(ctor); + metaMember = metaCtor; + metaParameter = GetMetaParameter(metaCtor, parameter); + break; + + case MethodInfo method: + MethodInfo metaMethod = GetMethodMetadataDefinition(method); + metaMember = metaMethod; + metaParameter = string.IsNullOrEmpty(parameter.Name) ? metaMethod.ReturnParameter : GetMetaParameter(metaMethod, parameter); + break; + + default: + return; + } - if (metaParameter != null) + if (metaParameter != null) + { + CheckGenericParameters(nullability, metaMember, metaParameter.ParameterType, parameter.Member.ReflectedType); + } + } + + private static ParameterInfo? GetMetaParameter(MethodBase metaMethod, ParameterInfo parameter) + { + var parameters = metaMethod.GetParameters(); + for (int i = 0; i < parameters.Length; i++) + { + if (parameter.Position == i && + parameter.Name == parameters[i].Name) { - CheckGenericParameters(nullability, metaMethod, metaParameter.ParameterType, parameter.Member.ReflectedType); + return parameters[i]; } } - } + return null; + } private static MethodInfo GetMethodMetadataDefinition(MethodInfo method) { if (method.IsGenericMethod && !method.IsGenericMethodDefinition) @@ -210,9 +222,7 @@ public NullabilityInfo Create(PropertyInfo propertyInfo) if (setter != null) { - var parameters = setter.GetParameters(); - - CheckNullabilityAttributes(nullability, parameters[parameters.Length-1].GetCustomAttributesData()); + CheckNullabilityAttributes(nullability, setter.GetParameters()[^1].GetCustomAttributesData()); } else { diff --git a/src/Tests/NullabilitySync.cs b/src/Tests/NullabilitySync.cs index 20496089..39385ba6 100644 --- a/src/Tests/NullabilitySync.cs +++ b/src/Tests/NullabilitySync.cs @@ -31,7 +31,9 @@ public async Task Run() """ var parameters = setter.GetParameters(); CheckNullabilityAttributes(nullability, parameters[parameters.Length-1].GetCustomAttributesData()); - """); + """) + .Replace("ReadOnlySpan parameters = metaMethod.GetParametersAsSpan();", "var parameters = metaMethod.GetParameters();") + .Replace(".GetParametersAsSpan()", ".GetParameters()"); var lines = infoContext.Split('\r', '\n'); infoContext = string.Join(Environment.NewLine, lines.Where(_ => !_.Contains("ArgumentNullException.ThrowIfNull")));