Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge in Feature/analyzers #713

Merged
31 commits merged into from Jul 2, 2020
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
cc70a0c
Add rudimentary analyzer runner and --fix-style option
jmarolf Jul 22, 2019
48a9e5a
Run diagnostic analyzers in parallel.
jmarolf Jul 23, 2019
38def36
Fix signing of third party components
jmarolf Jul 23, 2019
39f2981
Run code fixer after each analyzer.
JoeRobich Jul 23, 2019
003c51c
Refactor CodeFix Applier
RikkiGibson Jul 24, 2019
2be158a
Refactor AnalyzerRunner
JoeRobich Jul 24, 2019
0e2fc4b
Run formatters based on FormatType
jmarolf Jul 24, 2019
abaa89b
Log diagnostics and measure analysis time
JoeRobich Jul 26, 2019
011d916
Update solution only if its been changed
jmarolf Jul 27, 2019
895e583
Run diagnostics in parallel if in dry-run
jmarolf Jul 30, 2019
28f738a
Code cleanup and refactoring
JoeRobich Aug 2, 2019
49d01eb
Added reflection based discovery of analyzers and fixes
JoeRobich Jun 4, 2020
4351b5a
Bump version
JoeRobich Jun 4, 2020
93a6396
Await refactoring
JoeRobich Jun 5, 2020
7b8edc8
Moved parallelism to the AnalyzerRunner
JoeRobich Jun 5, 2020
128de98
Filter analyzers by severity before adding to compilation
JoeRobich Jun 7, 2020
577fbd1
Validate Roslyn CodeStyle.
JoeRobich Jun 7, 2020
f14c03f
Run DiagnosticAnalyzers from references
JoeRobich Jun 8, 2020
f063ce8
Comment out StyleCop reference
JoeRobich Jun 8, 2020
b7c20e4
Fix style error
JoeRobich Jun 8, 2020
e2b7721
Addressed PR feedback
JoeRobich Jun 9, 2020
507038a
Fix formatting issues
JoeRobich Jun 9, 2020
528bf3b
Merge pull request #698 from JoeRobich/add-reflection-discovery
JoeRobich Jun 9, 2020
0a5c927
add string localization
jmarolf Jun 22, 2020
adf693c
add analyzer reflection tests
jmarolf Jun 23, 2020
ea55ed1
Merge pull request #709 from jmarolf/fixup-analyzers-branch
jmarolf Jun 25, 2020
67a3428
Remove deprecated options and aliases
JoeRobich Jun 25, 2020
c0ca2c6
Make unit tests more reliable
JoeRobich Jun 25, 2020
95024cb
Merge pull request #710 from JoeRobich/update-options
JoeRobich Jun 25, 2020
5a6079e
Merge branch 'master' into feature/analyzers
jmarolf Jul 2, 2020
a85d00d
Fix up workspace argument test
JoeRobich Jul 2, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
30 changes: 15 additions & 15 deletions .editorconfig
Expand Up @@ -35,14 +35,14 @@ indent_size = 2
# 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:suggestion
dotnet_style_qualification_for_property = false:suggestion
dotnet_style_qualification_for_method = false:suggestion
dotnet_style_qualification_for_event = false:suggestion
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:suggestion
dotnet_style_predefined_type_for_member_access = true:suggestion
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
Expand Down Expand Up @@ -131,25 +131,25 @@ csharp_indent_switch_labels = true
csharp_indent_labels = flush_left

# Prefer "var" everywhere
csharp_style_var_for_built_in_types = true:suggestion
csharp_style_var_when_type_is_apparent = true:suggestion
csharp_style_var_elsewhere = true:suggestion
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 = false:none
csharp_style_expression_bodied_constructors = false:none
csharp_style_expression_bodied_operators = false:none

# Prefer property-like constructs to have an expression-body
csharp_style_expression_bodied_properties = true:none
csharp_style_expression_bodied_indexers = true:none
csharp_style_expression_bodied_accessors = true:none
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:suggestion
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
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_throw_expression = true:error
csharp_style_conditional_delegate_call = true:suggestion

# Newline settings
Expand Down
39 changes: 39 additions & 0 deletions .vscode/launch.json
Expand Up @@ -40,6 +40,45 @@
"console": "internalConsole",
"stopAtEntry": false
},
{
"name": "format format.sln --fix-style --check",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "publish",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/artifacts/bin/dotnet-format/Debug/netcoreapp2.1/publish/dotnet-format.dll",
"args": [
"format.sln",
"--fix-style",
"-v",
"diag",
"--check"
],
"cwd": "${workspaceFolder}",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole",
"stopAtEntry": false
},
{
"name": "format format.sln --fix-analyzers warn --check",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "publish",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/artifacts/bin/dotnet-format/Debug/netcoreapp2.1/publish/dotnet-format.dll",
"args": [
"format.sln",
"--fix-analyzers",
"warn",
"-v",
"diag",
"--check"
],
"cwd": "${workspaceFolder}",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole",
"stopAtEntry": false
},
{
"name": ".NET Core Attach",
"type": "coreclr",
Expand Down
82 changes: 42 additions & 40 deletions .vscode/tasks.json
@@ -1,42 +1,44 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/src/dotnet-format.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/src/dotnet-format.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"${workspaceFolder}/src/dotnet-format.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
}
]
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/src/dotnet-format.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/src/dotnet-format.csproj",
"-c",
"Debug",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"${workspaceFolder}/src/dotnet-format.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
}
]
}
4 changes: 3 additions & 1 deletion azure-pipelines.yml
Expand Up @@ -111,7 +111,9 @@ jobs:
vmImage: 'vs2017-win2016'
timeoutInMinutes: 5
steps:
- script: dotnet run --project ./src/dotnet-format.csproj -- @validate.rsp
- script: dotnet publish ./src/dotnet-format.csproj -c Release
displayName: Publish dotnet-format
- script: dotnet ./artifacts/bin/dotnet-format/Release/netcoreapp2.1/publish/dotnet-format.dll @validate.rsp
displayName: Run dotnet-format
- task: PublishBuildArtifacts@1
displayName: Publish Logs
Expand Down
4 changes: 2 additions & 2 deletions eng/Versions.props
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<PropertyGroup>
<MajorVersion>4</MajorVersion>
<MinorVersion>1</MinorVersion>
<MajorVersion>5</MajorVersion>
<MinorVersion>0</MinorVersion>
<!-- Build release-only package. -->
<PreReleaseVersionLabel />
</PropertyGroup>
Expand Down
12 changes: 12 additions & 0 deletions perf/FormattedFiles.cs
Expand Up @@ -34,6 +34,10 @@ public void FilesFormattedFolder()
workspacePath,
workspaceType,
LogLevel.Error,
fixCodeStyle: false,
codeStyleSeverity: DiagnosticSeverity.Error,
fixAnalyzers: false,
analyerSeverity: DiagnosticSeverity.Error,
saveFormattedFiles: false,
changesAreErrors: false,
AllFileMatcher,
Expand All @@ -50,6 +54,10 @@ public void FilesFormattedProject()
workspacePath,
workspaceType,
LogLevel.Error,
fixCodeStyle: false,
codeStyleSeverity: DiagnosticSeverity.Error,
fixAnalyzers: false,
analyerSeverity: DiagnosticSeverity.Error,
saveFormattedFiles: false,
changesAreErrors: false,
AllFileMatcher,
Expand All @@ -66,6 +74,10 @@ public void FilesFormattedSolution()
workspacePath,
workspaceType,
LogLevel.Error,
fixCodeStyle: false,
codeStyleSeverity: DiagnosticSeverity.Error,
fixAnalyzers: false,
analyerSeverity: DiagnosticSeverity.Error,
saveFormattedFiles: false,
changesAreErrors: false,
AllFileMatcher,
Expand Down
12 changes: 12 additions & 0 deletions perf/NoFilesFormatted.cs
Expand Up @@ -34,6 +34,10 @@ public void NoFilesFormattedFolder()
workspacePath,
workspaceType,
LogLevel.Error,
fixCodeStyle: false,
codeStyleSeverity: DiagnosticSeverity.Error,
fixAnalyzers: false,
analyerSeverity: DiagnosticSeverity.Error,
saveFormattedFiles: false,
changesAreErrors: false,
AllFileMatcher,
Expand All @@ -50,6 +54,10 @@ public void NoFilesFormattedProject()
workspacePath,
workspaceType,
LogLevel.Error,
fixCodeStyle: false,
codeStyleSeverity: DiagnosticSeverity.Error,
fixAnalyzers: false,
analyerSeverity: DiagnosticSeverity.Error,
saveFormattedFiles: false,
changesAreErrors: false,
AllFileMatcher,
Expand All @@ -66,6 +74,10 @@ public void NoFilesFormattedSolution()
workspacePath,
workspaceType,
LogLevel.Error,
fixCodeStyle: false,
codeStyleSeverity: DiagnosticSeverity.Error,
fixAnalyzers: false,
analyerSeverity: DiagnosticSeverity.Error,
saveFormattedFiles: false,
changesAreErrors: false,
AllFileMatcher,
Expand Down
8 changes: 8 additions & 0 deletions perf/RealWorldSolution.cs
Expand Up @@ -36,6 +36,10 @@ public void FilesFormattedSolution()
workspacePath,
workspaceType,
LogLevel.Error,
fixCodeStyle: false,
codeStyleSeverity: DiagnosticSeverity.Error,
fixAnalyzers: false,
analyerSeverity: DiagnosticSeverity.Error,
saveFormattedFiles: false,
changesAreErrors: false,
AllFileMatcher,
Expand All @@ -52,6 +56,10 @@ public void FilesFormattedFolder()
workspacePath,
workspaceType,
LogLevel.Error,
fixCodeStyle: false,
codeStyleSeverity: DiagnosticSeverity.Error,
fixAnalyzers: false,
analyerSeverity: DiagnosticSeverity.Error,
saveFormattedFiles: false,
changesAreErrors: false,
AllFileMatcher,
Expand Down
81 changes: 81 additions & 0 deletions src/Analyzers/AnalyzerFinderHelpers.cs
@@ -0,0 +1,81 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information.

using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;

using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.Diagnostics;

namespace Microsoft.CodeAnalysis.Tools.Analyzers
{
internal static class AnalyzerFinderHelpers
{
public static ImmutableArray<(DiagnosticAnalyzer Analyzer, CodeFixProvider? Fixer)> LoadAnalyzersAndFixers(IEnumerable<Assembly> assemblies)
{
var types = assemblies
.SelectMany(assembly => assembly.GetTypes()
.Where(type => !type.GetTypeInfo().IsInterface &&
!type.GetTypeInfo().IsAbstract &&
!type.GetTypeInfo().ContainsGenericParameters));

var codeFixProviders = types
.Where(t => typeof(CodeFixProvider).IsAssignableFrom(t))
.Select(type => type.TryCreateInstance<CodeFixProvider>(out var instance) ? instance : null)
.OfType<CodeFixProvider>()
.ToImmutableArray();

var diagnosticAnalyzers = types
.Where(t => typeof(DiagnosticAnalyzer).IsAssignableFrom(t))
.Select(type => type.TryCreateInstance<DiagnosticAnalyzer>(out var instance) ? instance : null)
.OfType<DiagnosticAnalyzer>()
.ToImmutableArray();

var builder = ImmutableArray.CreateBuilder<(DiagnosticAnalyzer Analyzer, CodeFixProvider? Fixer)>();
foreach (var diagnosticAnalyzer in diagnosticAnalyzers)
{
var diagnosticIds = diagnosticAnalyzer.SupportedDiagnostics.Select(diagnostic => diagnostic.Id).ToImmutableHashSet();
var codeFixProvider = codeFixProviders.FirstOrDefault(codeFixProvider => codeFixProvider.FixableDiagnosticIds.Any(id => diagnosticIds.Contains(id)));

if (codeFixProvider is null)
{
continue;
}

builder.Add((diagnosticAnalyzer, codeFixProvider));
}

return builder.ToImmutableArray();
}

public static async Task<ImmutableDictionary<Project, ImmutableArray<DiagnosticAnalyzer>>> FilterBySeverityAsync(
IEnumerable<Project> projects,
ImmutableArray<DiagnosticAnalyzer> allAnalyzers,
ImmutableHashSet<string> formattablePaths,
DiagnosticSeverity minimumSeverity,
CancellationToken cancellationToken)
{
var projectAnalyzers = ImmutableDictionary.CreateBuilder<Project, ImmutableArray<DiagnosticAnalyzer>>();
foreach (var project in projects)
{
var analyzers = ImmutableArray.CreateBuilder<DiagnosticAnalyzer>();

foreach (var analyzer in allAnalyzers)
{
var severity = await analyzer.GetSeverityAsync(project, formattablePaths, cancellationToken).ConfigureAwait(false);
if (severity >= minimumSeverity)
{
analyzers.Add(analyzer);
}
}

projectAnalyzers.Add(project, analyzers.ToImmutableArray());
}

return projectAnalyzers.ToImmutableDictionary();
}
}
}