Skip to content

Commit

Permalink
Merge pull request dotnet#698 from JoeRobich/add-reflection-discovery
Browse files Browse the repository at this point in the history
Added reflection based discovery of analyzers and fixes
  • Loading branch information
JoeRobich committed Jun 9, 2020
2 parents 73ce6c1 + c675ad2 commit 8e4da03
Show file tree
Hide file tree
Showing 41 changed files with 814 additions and 244 deletions.
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
11 changes: 0 additions & 11 deletions eng/Signing.props

This file was deleted.

2 changes: 1 addition & 1 deletion eng/Versions.props
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<PropertyGroup>
<MajorVersion>4</MajorVersion>
<MajorVersion>5</MajorVersion>
<MinorVersion>0</MinorVersion>
<!-- Build release-only package. -->
<PreReleaseVersionLabel />
Expand Down
15 changes: 12 additions & 3 deletions perf/FormattedFiles.cs
Expand Up @@ -34,7 +34,10 @@ public void FilesFormattedFolder()
workspacePath,
workspaceType,
LogLevel.Error,
FormatType.All,
fixCodeStyle: false,
codeStyleSeverity: DiagnosticSeverity.Error,
fixAnalyzers: false,
analyerSeverity: DiagnosticSeverity.Error,
saveFormattedFiles: false,
changesAreErrors: false,
AllFileMatcher,
Expand All @@ -51,7 +54,10 @@ public void FilesFormattedProject()
workspacePath,
workspaceType,
LogLevel.Error,
FormatType.All,
fixCodeStyle: false,
codeStyleSeverity: DiagnosticSeverity.Error,
fixAnalyzers: false,
analyerSeverity: DiagnosticSeverity.Error,
saveFormattedFiles: false,
changesAreErrors: false,
AllFileMatcher,
Expand All @@ -68,7 +74,10 @@ public void FilesFormattedSolution()
workspacePath,
workspaceType,
LogLevel.Error,
FormatType.All,
fixCodeStyle: false,
codeStyleSeverity: DiagnosticSeverity.Error,
fixAnalyzers: false,
analyerSeverity: DiagnosticSeverity.Error,
saveFormattedFiles: false,
changesAreErrors: false,
AllFileMatcher,
Expand Down
15 changes: 12 additions & 3 deletions perf/NoFilesFormatted.cs
Expand Up @@ -34,7 +34,10 @@ public void NoFilesFormattedFolder()
workspacePath,
workspaceType,
LogLevel.Error,
FormatType.All,
fixCodeStyle: false,
codeStyleSeverity: DiagnosticSeverity.Error,
fixAnalyzers: false,
analyerSeverity: DiagnosticSeverity.Error,
saveFormattedFiles: false,
changesAreErrors: false,
AllFileMatcher,
Expand All @@ -51,7 +54,10 @@ public void NoFilesFormattedProject()
workspacePath,
workspaceType,
LogLevel.Error,
FormatType.All,
fixCodeStyle: false,
codeStyleSeverity: DiagnosticSeverity.Error,
fixAnalyzers: false,
analyerSeverity: DiagnosticSeverity.Error,
saveFormattedFiles: false,
changesAreErrors: false,
AllFileMatcher,
Expand All @@ -68,7 +74,10 @@ public void NoFilesFormattedSolution()
workspacePath,
workspaceType,
LogLevel.Error,
FormatType.All,
fixCodeStyle: false,
codeStyleSeverity: DiagnosticSeverity.Error,
fixAnalyzers: false,
analyerSeverity: DiagnosticSeverity.Error,
saveFormattedFiles: false,
changesAreErrors: false,
AllFileMatcher,
Expand Down
10 changes: 8 additions & 2 deletions perf/RealWorldSolution.cs
Expand Up @@ -36,7 +36,10 @@ public void FilesFormattedSolution()
workspacePath,
workspaceType,
LogLevel.Error,
FormatType.All,
fixCodeStyle: false,
codeStyleSeverity: DiagnosticSeverity.Error,
fixAnalyzers: false,
analyerSeverity: DiagnosticSeverity.Error,
saveFormattedFiles: false,
changesAreErrors: false,
AllFileMatcher,
Expand All @@ -53,7 +56,10 @@ public void FilesFormattedFolder()
workspacePath,
workspaceType,
LogLevel.Error,
FormatType.All,
fixCodeStyle: false,
codeStyleSeverity: DiagnosticSeverity.Error,
fixAnalyzers: false,
analyerSeverity: DiagnosticSeverity.Error,
saveFormattedFiles: false,
changesAreErrors: false,
AllFileMatcher,
Expand Down
83 changes: 83 additions & 0 deletions src/Analyzers/AnalyzerFinderHelpers.cs
@@ -0,0 +1,83 @@
// 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;
using Microsoft.Extensions.Logging;

namespace Microsoft.CodeAnalysis.Tools.Analyzers
{
internal static class AnalyzerFinderHelpers
{
public static ImmutableArray<(DiagnosticAnalyzer Analyzer, CodeFixProvider? Fixer)> LoadAnalyzersAndFixers(
IEnumerable<Assembly> assemblies,
ILogger logger)
{
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();
}
}
}

0 comments on commit 8e4da03

Please sign in to comment.