# To learn more about .editorconfig see https://aka.ms/editorconfigdocs
###############################
# Core EditorConfig Options   #
###############################
root = true

# All files
[*]
indent_style = space

# Code files
[*.{cs,csx,vb,vbx}]
indent_size = 4
insert_final_newline = true
charset = utf-8-bom

# Visual Studio Solution Files
[*.sln]
indent_style = tab

# Visual Studio XML Project Files
[*.{csproj,vbproj,vcxproj.filters,proj,projitems,shproj}]
indent_size = 2

# XML Configuration Files
[*.{xml,config,props,targets,nuspec,resx,ruleset,vsixmanifest,vsct}]
indent_size = 2

# JSON Files
[*.{json,json5,webmanifest}]
indent_size = 2

# YAML Files
[*.{yml,yaml}]
indent_size = 2

###############################
# .NET Coding Conventions     #
###############################
[*.{cs,vb}]
tab_width = 4
trim_trailing_whitespace = true

# Namespace preferences
dotnet_sort_system_directives_first = true:suggestion
dotnet_style_namespace_match_folder = true:warning

# Organize using directives
# https://docs.microsoft.com/en-gb/dotnet/fundamentals/code-analysis/style-rules/formatting-rules#net-formatting-rules
dotnet_sort_system_directives_first = true
dotnet_separate_import_directive_groups = false

# this. preferences
dotnet_style_qualification_for_field = false:warning
dotnet_style_qualification_for_property = false:warning
dotnet_style_qualification_for_method = false:warning
dotnet_style_qualification_for_event = false:warning

# Language keywords vs BCL types preferences
dotnet_style_predefined_type_for_locals_parameters_members = true:warning
dotnet_style_predefined_type_for_member_access = true:warning

# Parentheses preferences
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:warning
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:warning
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:warning
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:warning

# Modifier preferences
dotnet_style_require_accessibility_modifiers = always:warning
dotnet_style_readonly_field = true:warning

# Expression-level preferences
dotnet_style_object_initializer = false:warning
dotnet_style_collection_initializer = true:none
dotnet_style_explicit_tuple_names = true:warning
dotnet_style_null_propagation = true:warning
dotnet_style_coalesce_expression = true:warning
dotnet_style_operator_placement_when_wrapping = beginning_of_line:warning
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:warning
dotnet_style_prefer_inferred_tuple_names = true:warning
dotnet_style_prefer_inferred_anonymous_type_member_names = true:warning
dotnet_style_prefer_auto_properties = true:warning
dotnet_style_prefer_conditional_expression_over_assignment = true:warning
dotnet_style_prefer_conditional_expression_over_return = true:warning
dotnet_style_prefer_simplified_boolean_expressions = true:warning
dotnet_style_prefer_compound_assignment = true:warning
dotnet_style_prefer_simplified_interpolation = true:warning

# Null-checking preferences
dotnet_style_coalesce_expression = true:warning
dotnet_style_null_propagation = true:warning
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:warning

# .NET Unnecessary code rules
dotnet_code_quality_unused_parameters = all:warning
# see https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0079 for why "none" is correct here
dotnet_remove_unnecessary_suppression_exclusions = none:warning

###############################
# Naming Conventions          #
###############################
# Style Definitions
dotnet_naming_style.pascal_case_style.capitalization = pascal_case
dotnet_naming_style.camel_case_style.capitalization = camel_case
dotnet_naming_style.upper_case_style.capitalization = all_upper
dotnet_naming_style.upper_case_style.word_separator = _

dotnet_naming_style.camel_case_with_underscore_style.capitalization = camel_case
dotnet_naming_style.camel_case_with_underscore_style.required_prefix = _

dotnet_naming_style.interface_style.capitalization = pascal_case
dotnet_naming_style.interface_style.required_prefix = I

dotnet_naming_style.async_method_style.capitalization = pascal_case
dotnet_naming_style.async_method_style.required_suffix = Async

# Symbol Definitions
dotnet_naming_symbols.interface_symbol.applicable_kinds = interface
dotnet_naming_symbols.interface_symbol.applicable_accessibilities = *

dotnet_naming_symbols.public_internal_members.applicable_kinds = property, method, field, event, delegate
dotnet_naming_symbols.public_internal_members.applicable_accessibilities = public, internal, protected, protected_internal

dotnet_naming_symbols.private_members.applicable_kinds = method, event, delegate
dotnet_naming_symbols.private_members.applicable_accessibilities = private, private_protected

dotnet_naming_symbols.private_static_readonly_members_symbols.applicable_kinds = property, field
dotnet_naming_symbols.private_static_readonly_members_symbols.applicable_accessibilities = private, private_protected
dotnet_naming_symbols.private_static_readonly_members_symbols.required_modifiers = static, readonly

dotnet_naming_symbols.private_fields.applicable_kinds = property, field
dotnet_naming_symbols.private_fields.applicable_accessibilities = private, private_protected

dotnet_naming_symbols.parameters_and_locals.applicable_kinds = parameter, local

dotnet_naming_symbols.const_fields.applicable_kinds = local, field
dotnet_naming_symbols.const_fields.required_modifiers = const

dotnet_naming_symbols.async_methods.applicable_kinds = method
dotnet_naming_symbols.async_methods.applicable_accessibilities = *
dotnet_naming_symbols.async_methods.required_modifiers = async

# Naming rules
# Use PascalCase for const fields and locals
dotnet_naming_rule.const_field_rule.severity = warning
dotnet_naming_rule.const_field_rule.symbols = const_fields
dotnet_naming_rule.const_field_rule.style = pascal_case_style

# Use PascalCase for public members
dotnet_naming_rule.public_internal_members_rule.severity = warning
dotnet_naming_rule.public_internal_members_rule.symbols = public_internal_members
dotnet_naming_rule.public_internal_members_rule.style = pascal_case_style

# Use PascalCase for private methods, events and delegates
dotnet_naming_rule.private_members_rule.severity = warning
dotnet_naming_rule.private_members_rule.symbols = private_members
dotnet_naming_rule.private_members_rule.style = pascal_case_style

# Use PascalCase for private static readonly fields
dotnet_naming_rule.private_static_readonly_members_rule.severity = warning
dotnet_naming_rule.private_static_readonly_members_rule.symbols = private_static_readonly_members_symbols
dotnet_naming_rule.private_static_readonly_members_rule.style = pascal_case_style

# Use camelCase with underscore for private fields
dotnet_naming_rule.private_field_rule.severity = warning
dotnet_naming_rule.private_field_rule.symbols = private_fields
dotnet_naming_rule.private_field_rule.style = camel_case_with_underscore_style

# Prefix interfaces with an I
dotnet_naming_rule.interface_rule.severity = warning
dotnet_naming_rule.interface_rule.symbols = interface_symbol
dotnet_naming_rule.interface_rule.style = interface_style

# Suffix async methods with "Async"
dotnet_naming_rule.async_method_rule.severity = warning
dotnet_naming_rule.async_method_rule.symbols = async_methods
dotnet_naming_rule.async_method_rule.style = async_method_style

# Use camelCase for local parameters and variables
dotnet_naming_rule.parameters_and_locals_rule.severity = warning
dotnet_naming_rule.parameters_and_locals_rule.symbols = parameters_and_locals
dotnet_naming_rule.parameters_and_locals_rule.style = camel_case_style

###############################
# Formatting Conventions      #
###############################

# Fix formatting
dotnet_diagnostic.IDE0055.severity = warning

# Avoid multiple blank lines
dotnet_diagnostic.IDE2000.severity = warning

# Consecutive braces must not have a blank line between them
dotnet_diagnostic.IDE2002.severity = warning
dotnet_style_prefer_collection_expression = when_types_exactly_match:warning
dotnet_style_allow_multiple_blank_lines_experimental = false:warning
dotnet_style_allow_statement_immediately_after_block_experimental = true:silent

###############################
# C# Coding Conventions       #
###############################

[*.cs]

# var preferences
csharp_style_var_for_built_in_types = true:warning
csharp_style_var_when_type_is_apparent = true:warning
csharp_style_var_elsewhere = true:warning

# Namespace preferences
csharp_style_namespace_declarations = file_scoped:warning
csharp_using_directive_placement = outside_namespace:silent

# Expression-bodied members
csharp_style_expression_bodied_methods = when_on_single_line:suggestion
csharp_style_expression_bodied_constructors = false:silent
csharp_style_expression_bodied_operators = when_on_single_line:warning
csharp_style_expression_bodied_properties = when_on_single_line:warning
csharp_style_expression_bodied_indexers = when_on_single_line:warning
csharp_style_expression_bodied_accessors = when_on_single_line:warning
csharp_style_expression_bodied_lambdas = false:silent
csharp_style_expression_bodied_local_functions = false:silent

# Pattern matching preferences
csharp_style_pattern_matching_over_is_with_cast_check = true:warning
csharp_style_pattern_matching_over_as_with_null_check = true:warning
csharp_style_prefer_switch_expression = true:warning
csharp_style_prefer_pattern_matching = true:warning
csharp_style_prefer_not_pattern = true:warning
csharp_style_prefer_extended_property_pattern = true:warning

# Null-checking preferences
csharp_style_throw_expression = true:warning
csharp_style_conditional_delegate_call = true:warning
csharp_style_prefer_null_check_over_type_check = true:warning

# Modifier preferences
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:warning

# Expression-level preferences
csharp_prefer_braces = true:warning
csharp_style_deconstructed_variable_declaration = true:warning
csharp_prefer_simple_default_expression = true:warning
dotnet_style_prefer_compound_assignment = true:warning
csharp_style_pattern_local_over_anonymous_function = true:warning
csharp_style_inlined_variable_declaration = true:warning
csharp_style_prefer_index_operator = true:warning
csharp_style_prefer_range_operator = true:warning
csharp_style_prefer_method_group_conversion = true:warning
dotnet_style_prefer_collection_expression = true:warning
csharp_style_implicit_object_creation_when_type_is_apparent = true:warning
csharp_style_prefer_utf8_string_literals = true:warning

# Unnecessary code rules
csharp_style_unused_value_assignment_preference = discard_variable:silent
csharp_style_unused_value_expression_statement_preference = discard_variable:silent

# Locals preferences
csharp_prefer_static_local_function = true:warning
csharp_style_prefer_local_over_anonymous_function = true:warning

# Misc
csharp_style_prefer_top_level_statements = true:warning
csharp_style_prefer_primary_constructors = true:suggestion
csharp_style_prefer_tuple_swap = true:warning
csharp_style_prefer_readonly_struct = true:warning
csharp_style_prefer_readonly_struct_member = true:warning

# IDE0063: Use simple 'using' statement
csharp_prefer_simple_using_statement = true:warning

# IDE0054: Use compound assignment
dotnet_diagnostic.IDE0054.severity = warning

# IDE0028: Simplify collection initialization
dotnet_diagnostic.IDE0028.severity = none


###############################
# C# Formatting Rules         #
###############################

# New line preferences
csharp_new_line_before_open_brace = all
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
csharp_new_line_between_query_expression_clauses = true

# Indentation preferences
csharp_indent_case_contents = true
csharp_indent_switch_labels = true
csharp_indent_labels = no_change
csharp_indent_block_contents = true
csharp_indent_braces = false
csharp_indent_case_contents_when_block = false

# Space preferences
csharp_space_after_cast = false
csharp_space_after_keywords_in_control_flow_statements = true
csharp_space_between_parentheses = false
csharp_space_before_colon_in_inheritance_clause = true
csharp_space_after_colon_in_inheritance_clause = true
csharp_space_around_binary_operators = before_and_after

csharp_space_between_method_declaration_parameter_list_parentheses = false
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
csharp_space_between_method_declaration_name_and_open_parenthesis = false
csharp_space_between_method_call_parameter_list_parentheses = false
csharp_space_between_method_call_empty_parameter_list_parentheses = false
csharp_space_between_method_call_name_and_opening_parenthesis = false
csharp_space_after_comma = true
csharp_space_before_comma = false
csharp_space_after_dot = false
csharp_space_before_dot = false
csharp_space_after_semicolon_in_for_statement = true
csharp_space_before_semicolon_in_for_statement = false
csharp_space_around_declaration_statements = false
csharp_space_before_open_square_brackets = false
csharp_space_between_empty_square_brackets = false
csharp_space_between_square_brackets = false

csharp_style_allow_embedded_statements_on_same_line_experimental = true:silent
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true:silent
csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true:silent
csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true:silent
csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true:silent

# Wrapping preferences
csharp_preserve_single_line_statements = false
csharp_preserve_single_line_blocks = true

###############################
# Analyzer Rules              #
###############################

# CA5394: Do not use insecure randomness
dotnet_diagnostic.CA5394.severity = none

# CA2234: Pass system uri objects instead of strings
dotnet_diagnostic.CA2234.severity = none

# IDE0072: Add missing cases
# According to https://github.com/dotnet/roslyn/issues/66433
# this is not intended to have a severity set.
dotnet_diagnostic.IDE0072.severity = none
