Code analysis
De Banane Atomic
Aller à la navigationAller à la recherche
Code analysis
Code quality analysis
Those rules are enabled by default.
Here is how to enabled additional rules:
MyProject.csproj |
<PropertyGroup> <!-- ... --> <AnalysisLevel>latest-recommended</AnalysisLevel> </PropertyGroup> |
Prefer the use of editorconfig to globalconfig |
.globalconfig |
# Top level entry required to mark this as a global AnalyzerConfig file is_global = true # NOTE: No section headers for configuration entries #### .NET Coding Conventions #### # this. and Me. preferences dotnet_style_qualification_for_method = true:warning #### Diagnostic configuration #### # CA2007: Do not directly await a Task dotnet_diagnostic.CA2007.severity = none |
Code style analysis
# verify that all code is correctly formatted dotnet format --verify-no-changes # format all code dotnet format |
- Configuration files for code analysis rules
- An example of .editorconfig file with the default options
- Code-style rules IDExxxx
- Change encoding
.editorconfig |
############################### # Core EditorConfig Options # ############################### root = true # All files [*] indent_style = space insert_final_newline = true charset = utf-8 # XML project files [*.csproj] indent_size = 2 # JSON config files [*.json] indent_size = 2 # C# code files [*.cs] indent_size = 4 trim_trailing_whitespace = true ############################### # Analyzer configuration # ############################### # set the rules severity to warning dotnet_analyzer_diagnostic.severity = warning # speller dotnet_diagnostic.VSSpell001.severity = suggestion dotnet_diagnostic.VSSpell002.severity = suggestion ############################### # .NET Coding Conventions # ############################### [*.cs] # Organize usings dotnet_sort_system_directives_first = true ############################### # Code Quality configuration # ############################### # CA1826: Use property instead of Linq Enumerable method # Exclude FirstOrDefault and LastOrDefault methods dotnet_code_quality.CA1826.exclude_ordefault_methods = true ############################### # Style configuration # ############################### # IDE0003 / IDE0009: this and Me preferences dotnet_style_qualification_for_field = true # IDE0007 / IDE0008: 'var' preferences csharp_style_var_for_built_in_types = true csharp_style_var_when_type_is_apparent = true csharp_style_var_elsewhere = true : silent # IDE0011: Add braces csharp_prefer_braces = when_multiline # IDE0022: Use expression body for methods csharp_style_expression_bodied_methods = when_on_single_line # IDE0160 / IDE0161: Namespace declaration preferences csharp_style_namespace_declarations = file_scoped : error ############################### # Disabled rules # ############################### # IDE0046: Use conditional expression for return dotnet_diagnostic.IDE0046.severity = suggestion # IDE0058: Remove unnecessary expression value dotnet_diagnostic.IDE0058.severity = none # CA1305: Specify IFormatProvider dotnet_diagnostic.CA1305.severity = none # CA1310: Specify StringComparison for correctness dotnet_diagnostic.CA1310.severity = none # Specify CultureInfo dotnet_diagnostic.CA1304.severity = suggestion # Specify a culture dotnet_diagnostic.CA1311.severity = suggestion ############################### # Naming Conventions # ############################### # Style Definitions dotnet_naming_style.upper_case_style.capitalization = all_upper dotnet_naming_style.camel_case_style.capitalization = camel_case # Use UpperCase for constant fields dotnet_naming_symbols.constant_fields.applicable_kinds = field dotnet_naming_symbols.constant_fields.required_modifiers = const dotnet_naming_rule.constant_fields_should_be_upper_case.symbols = constant_fields dotnet_naming_rule.constant_fields_should_be_upper_case.style = upper_case_style dotnet_naming_rule.constant_fields_should_be_upper_case.severity = warning # Use camelCase for variables dotnet_naming_symbols.local_symbol.applicable_kinds = local dotnet_naming_rule.variables_should_be_camel_case.symbols = local_symbol dotnet_naming_rule.variables_should_be_camel_case.style = camel_case_style dotnet_naming_rule.variables_should_be_camel_case.severity = warning # Use camelCase for parameters dotnet_naming_symbols.parameter_symbol.applicable_kinds = parameter dotnet_naming_rule.parameters_should_be_camel_case.symbols = parameter_symbol dotnet_naming_rule.parameters_should_be_camel_case.style = camel_case_style dotnet_naming_rule.parameters_should_be_camel_case.severity = warning # Async methods should have "Async" suffix dotnet_naming_rule.async_methods_end_in_async.symbols = any_async_methods dotnet_naming_rule.async_methods_end_in_async.style = end_in_async dotnet_naming_rule.async_methods_end_in_async.severity = suggestion dotnet_naming_symbols.any_async_methods.applicable_kinds = method dotnet_naming_symbols.any_async_methods.applicable_accessibilities = * dotnet_naming_symbols.any_async_methods.required_modifiers = async dotnet_naming_style.end_in_async.required_prefix = dotnet_naming_style.end_in_async.required_suffix = Async dotnet_naming_style.end_in_async.capitalization = pascal_case dotnet_naming_style.end_in_async.word_separator = |
Visual Studio Code integration
settings.json |
"omnisharp.enableRoslynAnalyzers": true, "omnisharp.enableEditorConfigSupport": true, |
Visual Studio
Set the scope of live code analysis
- Tools → Options
- Text Editor → C# → Advanced
- Run background code analysis for: Current document
- Show compiler errors and warnings for: Open documents
Roslynator
- Install the Roslynator extension in Visual Studio or Visual Studio Code
- Configure Roslynator on a user-wide basis
- vscode → Ctrl + Shift + P → enter roslynator → select Roslynator: Open Default Configuration File (.roslynatorconfig)
~/.local/share/JosefPihrt/Roslynator/.roslynatorconfig |
is_global = true # enable all analyzers by default and set the severity to warning roslynator_analyzers.enabled_by_default = true dotnet_analyzer_diagnostic.category-roslynator.severity = warning # enable all refactorings roslynator_refactorings.enabled = true # enable all compiler diagnostic fixes roslynator_compiler_diagnostic_fixes.enabled = true # Options roslynator_accessibility_modifiers = explicit roslynator_accessor_braces_style = single_line_when_expression_is_on_single_line roslynator_array_creation_type_style = implicit_when_type_is_obvious roslynator_arrow_token_new_line = before roslynator_binary_operator_new_line = before roslynator_blank_line_after_file_scoped_namespace_declaration = true roslynator_blank_line_between_closing_brace_and_switch_section = false roslynator_blank_line_between_single_line_accessors = false roslynator_blank_line_between_using_directives = never roslynator_block_braces_style = single_line_when_empty #roslynator_body_style = block|expression roslynator_conditional_operator_condition_parentheses_style = omit roslynator_conditional_operator_new_line = beforeroslynator_configure_await = false roslynator_doc_comment_summary_style = multi_line roslynator_empty_string_style = field roslynator_enum_flag_value_style = decimal_number roslynator_enum_has_flag_style = method roslynator_equals_token_new_line = before roslynator_infinite_loop_style = while roslynator_max_line_length = 140 roslynator_new_line_at_end_of_file = false roslynator_new_line_before_while_in_do_statement = false roslynator_null_conditional_operator_new_line = before roslynator_null_check_style = pattern_matching roslynator_object_creation_parentheses_style = omit roslynator_object_creation_type_style = implicit_when_type_is_obvious roslynator_prefix_field_identifier_with_underscore = false roslynator_suppress_unity_script_methods = true roslynator_use_anonymous_function_or_method_group = method_group roslynator_use_block_body_when_declaration_spans_over_multiple_lines = true roslynator_use_block_body_when_expression_spans_over_multiple_lines = true roslynator_use_var_instead_of_implicit_object_creation = true # Analyzers # Add blank line between single-line declarations dotnet_diagnostic.rcs0012.severity = none # Remove braces from if-else dotnet_diagnostic.rcs1004.severity = none # Use explicit type instead of 'var' (when the type is not obvious) dotnet_diagnostic.rcs1008.severity = none # Use explicit type instead of 'var' (foreach variable) dotnet_diagnostic.rcs1009.severity = none # Use explicit type instead of 'var' (when the type is obvious) dotnet_diagnostic.rcs1012.severity = none # Avoid unnecessary boxing of value type dotnet_diagnostic.rcs1198.severity = none # Mark publicly visible type with DebuggerDisplay attribute dotnet_diagnostic.rcs1223.severity = none |
Roslynator CLI
# install dotnet tool install -g roslynator.dotnet.cli roslynator analyze \ --analyzer-assemblies \ ~/.vscode/extensions/josefpihrt-vscode.roslynator-4.3.0/roslyn/common \ ~/.vscode/extensions/josefpihrt-vscode.roslynator-4.3.0/roslyn/analyzers |
To fix the error: Could not load file or assembly 'System.Composition.AttributedModel, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
|
Code coverage
# add the XunitXML.TestLogger nuget package to the unit test project dotnet add package XunitXML.TestLogger # run unit tests with Coverlet data collector and log the results dotnet test MySolution.sln --collect="XPlat Code Coverage" --logger:"xunit;LogFilePath=TestResults.xml" # creates a TestResults.xml report and a TestResults/[guid]/coverage.cobertura.xml report # extract the line coverage: xmllint --xpath "string(/coverage/@line-rate)" TestResults/[guid]/coverage.cobertura.xml sed -n -r 's/<coverage line-rate="([0-9.]+)".*/\1/p' TestResults/[guid]/coverage.cobertura.xml # install the ReportGenerator tool dotnet tool install -g dotnet-reportgenerator-globaltool # get a text summary report from all the cobertura reports reportgenerator -reports:"*/TestResults/*/coverage.cobertura.xml" -targetdir:CoverageReport -reporttypes:TextSummary # creates CoverageReport/TextSummary.txt # extract the line coverage: sed -n -r 's/Line coverage: ([0-9.]+)%/\1/p' CoverageReport/Summary.txt |
Ignore generated code
Create an .editorconfig file in a folder to not run code analysis on the files of this folder.
MyWebapi/DataAccess/.editorconfig |
[*] generated_code = true dotnet_analyzer_diagnostic.severity = silent |