From b88fdafaaf3dc6ede54c7e3537dc454d8f3c015b Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 3 Oct 2023 08:40:21 +1100 Subject: [PATCH] Re sync nullability code (#95) --- api_list.include.md | 10 +- readme.md | 10 +- src/Directory.Build.props | 2 +- .../Nullability/NullabilityInfoContext.cs | 58 +++--- src/Tests/NullabilitySync.cs | 6 +- src/editorconfig.txt | 169 ++++++++++++++++++ 6 files changed, 219 insertions(+), 36 deletions(-) create mode 100644 src/editorconfig.txt 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/Directory.Build.props b/src/Directory.Build.props index 7d907adf..15e15feb 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,7 @@ - 1.28.0 + 1.29.0 1.0.0 Polyfill true diff --git a/src/Polyfill/Nullability/NullabilityInfoContext.cs b/src/Polyfill/Nullability/NullabilityInfoContext.cs index 18964394..a2939cdb 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) + { + CheckGenericParameters(nullability, metaMember, metaParameter.ParameterType, parameter.Member.ReflectedType); + } + } - if (metaParameter != null) + 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) diff --git a/src/Tests/NullabilitySync.cs b/src/Tests/NullabilitySync.cs index 20496089..ceab6b5a 100644 --- a/src/Tests/NullabilitySync.cs +++ b/src/Tests/NullabilitySync.cs @@ -27,11 +27,13 @@ public async Task Run() .Replace(".IsGenericMethodParameter", ".IsGenericMethodParameter()") .Replace("SR.NullabilityInfoContext_NotSupported", "\"NullabilityInfoContext is not supported\"") .Replace( - "CheckNullabilityAttributes(nullability, setter.GetParameters()[^1].GetCustomAttributesData());", + "CheckNullabilityAttributes(nullability, setter.GetParametersAsSpan()[^1].GetCustomAttributesData());", """ 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"))); diff --git a/src/editorconfig.txt b/src/editorconfig.txt new file mode 100644 index 00000000..bb59b63e --- /dev/null +++ b/src/editorconfig.txt @@ -0,0 +1,169 @@ +root = true +# EditorConfig: http://EditorConfig.org + +# top-most EditorConfig file + +[*] +indent_style = space + + +[*.cs] +indent_size = 4 +charset = utf-8 + + +# Microsoft .NET properties +trim_trailing_whitespace = true +csharp_preferred_modifier_order = public, private, protected, internal, new, static, abstract, virtual, sealed, readonly, override, extern, unsafe, volatile, async:suggestion +resharper_namespace_body = file_scoped +dotnet_naming_rule.private_constants_rule.severity = warning +dotnet_naming_rule.private_constants_rule.style = upper_camel_case_style +dotnet_naming_rule.private_constants_rule.symbols = private_constants_symbols +dotnet_naming_rule.private_instance_fields_rule.severity = warning +dotnet_naming_rule.private_instance_fields_rule.style = lower_camel_case_style +dotnet_naming_rule.private_instance_fields_rule.symbols = private_instance_fields_symbols +dotnet_naming_rule.private_static_fields_rule.severity = warning +dotnet_naming_rule.private_static_fields_rule.style = lower_camel_case_style +dotnet_naming_rule.private_static_fields_rule.symbols = private_static_fields_symbols +dotnet_naming_rule.private_static_readonly_rule.severity = warning +dotnet_naming_rule.private_static_readonly_rule.style = upper_camel_case_style +dotnet_naming_rule.private_static_readonly_rule.symbols = private_static_readonly_symbols +dotnet_naming_style.lower_camel_case_style.capitalization = camel_case +dotnet_naming_style.upper_camel_case_style.capitalization = pascal_case +dotnet_naming_symbols.private_constants_symbols.applicable_accessibilities = private +dotnet_naming_symbols.private_constants_symbols.applicable_kinds = field +dotnet_naming_symbols.private_constants_symbols.required_modifiers = const +dotnet_naming_symbols.private_instance_fields_symbols.applicable_accessibilities = private +dotnet_naming_symbols.private_instance_fields_symbols.applicable_kinds = field +dotnet_naming_symbols.private_static_fields_symbols.applicable_accessibilities = private +dotnet_naming_symbols.private_static_fields_symbols.applicable_kinds = field +dotnet_naming_symbols.private_static_fields_symbols.required_modifiers = static +dotnet_naming_symbols.private_static_readonly_symbols.applicable_accessibilities = private +dotnet_naming_symbols.private_static_readonly_symbols.applicable_kinds = field +dotnet_naming_symbols.private_static_readonly_symbols.required_modifiers = static, readonly +dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:none +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:none +dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:none + +# ReSharper properties +resharper_object_creation_when_type_not_evident = target_typed + +# ReSharper inspection severities +resharper_arrange_object_creation_when_type_evident_highlighting = error +resharper_arrange_object_creation_when_type_not_evident_highlighting = error +resharper_arrange_redundant_parentheses_highlighting = error +resharper_arrange_static_member_qualifier_highlighting = error +resharper_arrange_this_qualifier_highlighting = hint +resharper_arrange_type_member_modifiers_highlighting = none +resharper_built_in_type_reference_style_for_member_access_highlighting = hint +resharper_built_in_type_reference_style_highlighting = hint +resharper_check_namespace_highlighting = none +resharper_convert_to_using_declaration_highlighting = error +resharper_css_not_resolved_highlighting = warning +resharper_field_can_be_made_read_only_local_highlighting = none +resharper_merge_into_logical_pattern_highlighting = warning +resharper_merge_into_pattern_highlighting = error +resharper_method_has_async_overload_highlighting = warning +resharper_partial_type_with_single_part_highlighting = error +resharper_redundant_base_qualifier_highlighting = warning +resharper_redundant_cast_highlighting = error +resharper_redundant_empty_object_creation_argument_list_highlighting = error +resharper_redundant_empty_object_or_collection_initializer_highlighting = error +resharper_redundant_name_qualifier_highlighting = error +resharper_redundant_suppress_nullable_warning_expression_highlighting = error +resharper_redundant_using_directive_highlighting = error +resharper_redundant_verbatim_string_prefix_highlighting = error +resharper_replace_substring_with_range_indexer_highlighting = warning +resharper_suggest_var_or_type_built_in_types_highlighting = error +resharper_suggest_var_or_type_elsewhere_highlighting = error +resharper_suggest_var_or_type_simple_types_highlighting = error +resharper_unnecessary_whitespace_highlighting = error +resharper_use_await_using_highlighting = warning +resharper_use_deconstruction_highlighting = warning + +# Sort using and Import directives with System.* appearing first +dotnet_sort_system_directives_first = true + +# Avoid "this." and "Me." if not necessary +dotnet_style_qualification_for_field = false:error +dotnet_style_qualification_for_property = false:error +dotnet_style_qualification_for_method = false:error +dotnet_style_qualification_for_event = false:error + +# Use language keywords instead of framework type names for type references +dotnet_style_predefined_type_for_locals_parameters_members = true:error +dotnet_style_predefined_type_for_member_access = true:error + +# Suggest more modern language features when available +dotnet_style_object_initializer = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_coalesce_expression = false:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_explicit_tuple_names = true:suggestion + +# Prefer "var" everywhere +csharp_style_var_for_built_in_types = true:error +csharp_style_var_when_type_is_apparent = true:error +csharp_style_var_elsewhere = true:error + +# Prefer method-like constructs to have a block body +csharp_style_expression_bodied_methods = true:error +csharp_style_expression_bodied_local_functions = true:error +csharp_style_expression_bodied_constructors = true:error +csharp_style_expression_bodied_operators = true:error +resharper_place_expr_method_on_single_line = false + +# Prefer property-like constructs to have an expression-body +csharp_style_expression_bodied_properties = true:error +csharp_style_expression_bodied_indexers = true:error +csharp_style_expression_bodied_accessors = true:error + +# Suggest more modern language features when available +csharp_style_pattern_matching_over_is_with_cast_check = true:error +csharp_style_pattern_matching_over_as_with_null_check = true:error +csharp_style_inlined_variable_declaration = true:suggestion +csharp_style_throw_expression = true:suggestion +csharp_style_conditional_delegate_call = true:suggestion + +# Newline settings +#csharp_new_line_before_open_brace = all:error +resharper_max_array_initializer_elements_on_line = 1 +csharp_new_line_before_else = true +csharp_new_line_before_catch = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_members_in_anonymous_types = true +resharper_wrap_before_first_type_parameter_constraint = true +resharper_wrap_extends_list_style = chop_always +resharper_wrap_after_dot_in_method_calls = false +resharper_wrap_before_binary_pattern_op = false +resharper_wrap_object_and_collection_initializer_style = chop_always +resharper_place_simple_initializer_on_single_line = false + +# space +resharper_space_around_lambda_arrow = true + +dotnet_style_require_accessibility_modifiers = never:error +resharper_place_type_constraints_on_same_line = false +resharper_blank_lines_inside_namespace = 0 +resharper_blank_lines_after_file_scoped_namespace_directive = 1 +resharper_blank_lines_inside_type = 0 + +#braces https://www.jetbrains.com/help/resharper/EditorConfig_CSHARP_CSharpCodeStylePageImplSchema.html#Braces +resharper_braces_for_ifelse = required +resharper_braces_for_foreach = required +resharper_braces_for_while = required +resharper_braces_for_dowhile = required +resharper_braces_for_lock = required +resharper_braces_for_fixed = required +resharper_braces_for_for = required + +# Xml files +[*.{xml,config,nuspec,resx,vsixmanifest,csproj,targets,props}] +indent_size = 2 +# https://www.jetbrains.com/help/resharper/EditorConfig_XML_XmlCodeStylePageSchema.html#resharper_xml_blank_line_after_pi +resharper_blank_line_after_pi = false +resharper_space_before_self_closing = true + +[*.json] +indent_size = 2 \ No newline at end of file