-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[GH-11] - code fix provider for adding suppressions to nsubstitute.json
- Loading branch information
Showing
7 changed files
with
128 additions
and
96 deletions.
There are no files selected for viewing
11 changes: 11 additions & 0 deletions
11
...Substitute.Analyzers.CSharp/CodeFixProviders/DefaultSuppressDiagnosticsCodeFixProvider.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CodeFixes; | ||
using NSubstitute.Analyzers.Shared.CodeFixProviders; | ||
|
||
namespace NSubstitute.Analyzers.CSharp.CodeFixProviders | ||
{ | ||
[ExportCodeFixProvider(LanguageNames.CSharp)] | ||
public class DefaultSuppressDiagnosticsCodeFixProvider : AbstractSuppressDiagnosticsCodeFixProvider | ||
{ | ||
} | ||
} |
76 changes: 0 additions & 76 deletions
76
src/NSubstitute.Analyzers.CSharp/CodeFixProviders/SupressDiagnosticCodeFixProvider.cs
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
112 changes: 112 additions & 0 deletions
112
...ubstitute.Analyzers.Shared/CodeFixProviders/AbstractSuppressDiagnosticsCodeFixProvider.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Collections.Immutable; | ||
using System.Linq; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CodeActions; | ||
using Microsoft.CodeAnalysis.CodeFixes; | ||
using Newtonsoft.Json; | ||
using NSubstitute.Analyzers.Shared.Extensions; | ||
using NSubstitute.Analyzers.Shared.Settings; | ||
using NSubstitute.Analyzers.Shared.Threading; | ||
|
||
namespace NSubstitute.Analyzers.Shared.CodeFixProviders | ||
{ | ||
public class AbstractSuppressDiagnosticsCodeFixProvider : CodeFixProvider | ||
{ | ||
public override ImmutableArray<string> FixableDiagnosticIds { get; } = ImmutableArray.Create(DiagnosticIdentifiers.NonVirtualSetupSpecification); | ||
|
||
public override Task RegisterCodeFixesAsync(CodeFixContext context) | ||
{ | ||
var project = context.Document.Project; | ||
var workspace = project.Solution.Workspace; | ||
|
||
// check if we are allowed to add it | ||
if (!workspace.CanApplyChange(ApplyChangesKind.AddAdditionalDocument)) | ||
{ | ||
return SpecializedTasks.CompletedTask; | ||
} | ||
|
||
foreach (var diagnostic in context.Diagnostics.Where(diagnostic => FixableDiagnosticIds.Contains(diagnostic.Id))) | ||
{ | ||
context.RegisterCodeFix( | ||
CodeAction.Create( | ||
"Suppress in nsubstitute.json", | ||
cancellationToken => GetTransformedSolutionAsync(context, diagnostic), | ||
nameof(AbstractSuppressDiagnosticsCodeFixProvider)), | ||
diagnostic); | ||
} | ||
|
||
return SpecializedTasks.CompletedTask; | ||
} | ||
|
||
private async Task<Solution> GetTransformedSolutionAsync(CodeFixContext context, Diagnostic diagnostic) | ||
{ | ||
var project = context.Document.Project; | ||
var solution = project.Solution; | ||
|
||
var settingsFile = GetSettingsFile(project); | ||
|
||
// creating additional document from Roslyn is broken (https://github.com/dotnet/roslyn/issues/4655) the nsubstitute.json file have to be created by users manually | ||
// if there is no settings file do not provide refactorings | ||
if (settingsFile == null) | ||
{ | ||
return solution; | ||
} | ||
|
||
var root = await context.Document.GetSyntaxRootAsync(); | ||
var model = await context.Document.GetSemanticModelAsync(); | ||
|
||
var syntaxNode = root.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true); | ||
var symbol = model.GetSymbolInfo(syntaxNode); | ||
|
||
var options = GetUpdatedAnalyzersOptions(context, diagnostic, symbol); | ||
|
||
project = project.RemoveAdditionalDocument(settingsFile.Id); | ||
solution = project.Solution; | ||
|
||
var newDocumentId = settingsFile.Id ?? DocumentId.CreateNewId(project.Id); | ||
|
||
return solution.AddAdditionalDocument( | ||
newDocumentId, | ||
AnalyzersSettings.AnalyzerFileName, | ||
JsonConvert.SerializeObject(options, Formatting.Indented)); | ||
} | ||
|
||
private static AnalyzersSettings GetUpdatedAnalyzersOptions(CodeFixContext context, Diagnostic diagnostic, SymbolInfo symbol) | ||
{ | ||
var options = context.Document.Project.AnalyzerOptions.GetSettings(default(CancellationToken)); | ||
var target = DocumentationCommentId.CreateDeclarationId(symbol.Symbol); | ||
options.Suppressions = options.Suppressions ?? new List<Suppression>(); | ||
|
||
var existingSuppression = options.Suppressions.FirstOrDefault(suppression => suppression.Target == target); | ||
|
||
if (existingSuppression != null) | ||
{ | ||
existingSuppression.Rules = existingSuppression.Rules ?? new List<string>(); | ||
existingSuppression.Rules.Add(diagnostic.Id); | ||
} | ||
else | ||
{ | ||
options.Suppressions.Add(new Suppression | ||
{ | ||
Target = DocumentationCommentId.CreateDeclarationId(symbol.Symbol), | ||
Rules = new List<string> | ||
{ | ||
diagnostic.Id | ||
} | ||
}); | ||
} | ||
|
||
return options; | ||
} | ||
|
||
private static TextDocument GetSettingsFile(Project project) | ||
{ | ||
return project.AdditionalDocuments.SingleOrDefault(document => | ||
document.Name.Equals(AnalyzersSettings.AnalyzerFileName, StringComparison.CurrentCultureIgnoreCase)); | ||
} | ||
} | ||
} |
15 changes: 0 additions & 15 deletions
15
src/NSubstitute.Analyzers.Shared/Extensions/AdditionalTextExtensions.cs
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters