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 main to main-vs-deps #61877

Merged
merged 32 commits into from
Jun 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
56a54ea
allow third party codfixers to be run in code cleanup
jmarolf Feb 16, 2022
af0bc75
adding tests
jmarolf Feb 23, 2022
66c49e2
Update src/Features/Core/Portable/CodeCleanup/AbstractCodeCleanupServ…
jmarolf Feb 23, 2022
07715b7
Update src/Features/Core/Portable/CodeCleanup/AbstractCodeCleanupServ…
jmarolf Feb 23, 2022
2a3af87
Update src/Features/Core/Portable/CodeFixes/CodeFixService.cs
jmarolf Feb 23, 2022
51fd876
Exports in test code should have [PartNotDiscoverable] applied.
jmarolf Feb 23, 2022
3c2ee92
rename severity to minimumSeverity for clarity
jmarolf Feb 23, 2022
a75df91
mark mef exported test types as `PartNotDiscoverable`
jmarolf Feb 23, 2022
1837a33
move VB tests to VB test assembly
jmarolf Feb 23, 2022
e5966af
move old members to extension method
jmarolf Feb 23, 2022
32bcffa
filter compiler diagnostics in Diagnostic Service call
jmarolf Feb 23, 2022
e737f03
report progress per third party fixer
jmarolf Feb 23, 2022
f5d6a2d
Do not apply fixes that change more than the current document
jmarolf Feb 23, 2022
1323127
add additional C# test cases
jmarolf Feb 24, 2022
bbb242a
adding additional VB tests
jmarolf Feb 24, 2022
0678c67
use helper methods
jmarolf Mar 1, 2022
3475811
enable nullable tracking for test fixes
jmarolf Mar 1, 2022
0c2c910
Update src/Features/Core/Portable/CodeCleanup/AbstractCodeCleanupServ…
jmarolf Mar 2, 2022
ad987bf
rename method for clarity
jmarolf Mar 4, 2022
be77781
update progress to never "rewind" and report the correct number of fi…
jmarolf Mar 4, 2022
c934e6c
pass a bool to let the diagnostic service filter out compiler diagnos…
jmarolf Mar 5, 2022
5a1740a
do not make includeCompilerDiagnostics optional
jmarolf Mar 7, 2022
777d073
change wording to match mikas suggestion
jmarolf Mar 15, 2022
dbf67f3
move the progress reporting to never "rewind" and instead report ever…
jmarolf Mar 15, 2022
23a0e4d
convert EnabledDiagnosticOptions to a record
jmarolf Mar 15, 2022
e41f176
add a an option that lets you run everything
jmarolf Mar 15, 2022
73f608a
pass parameter through to service
jmarolf Jun 7, 2022
c8941d5
fixup test (unnecessary async keyword is now removed)
jmarolf Jun 8, 2022
bf9c690
Update src/VisualStudio/Core/Def/CodeCleanup/AbstractCodeCleanUpFixer.cs
jmarolf Jun 14, 2022
04cf0c8
fixup variable rename
jmarolf Jun 14, 2022
dff871c
correctly pas arguments so we get compiler diagnostics
jmarolf Jun 14, 2022
06f579b
Merge pull request #59631 from jmarolf/feature/run-third-party-codefi…
jmarolf Jun 14, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ public static bool TryGetMappedOptions(string diagnosticId, string language, [No
(s_diagnosticIdToLanguageSpecificOptionsMap.TryGetValue(language, out var map) &&
map.TryGetValue(diagnosticId, out options));

public static bool IsKnownIDEDiagnosticId(string diagnosticId)
=> s_diagnosticIdToOptionMap.ContainsKey(diagnosticId) ||
s_diagnosticIdToLanguageSpecificOptionsMap.Values.Any(map => map.ContainsKey(diagnosticId));

public static void AddOptionMapping(string diagnosticId, ImmutableHashSet<IPerLanguageOption> perLanguageOptions)
{
diagnosticId = diagnosticId ?? throw new ArgumentNullException(nameof(diagnosticId));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,8 +267,8 @@ internal class CSharpCodeCleanupService : AbstractCodeCleanupService

[ImportingConstructor]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
public CSharpCodeCleanupService(ICodeFixService codeFixService)
: base(codeFixService)
public CSharpCodeCleanupService(ICodeFixService codeFixService, IDiagnosticAnalyzerService diagnosticAnalyzerService)
: base(codeFixService, diagnosticAnalyzerService)
{
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Composition;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.Text;

namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Formatting
{
public partial class CodeCleanupTests
{
private abstract class TestThirdPartyCodeFix : CodeFixProvider
{
public override ImmutableArray<string> FixableDiagnosticIds { get; } = ImmutableArray.Create("HasDefaultCase");

public override Task RegisterCodeFixesAsync(CodeFixContext context)
{
foreach (var diagnostic in context.Diagnostics)
{
context.RegisterCodeFix(
CodeAction.Create(
"Remove default case",
async cancellationToken =>
{
var root = await context.Document.GetSyntaxRootAsync(cancellationToken);
Assumes.NotNull(root);
var sourceTree = diagnostic.Location.SourceTree;
Assumes.NotNull(sourceTree);
var node = (await sourceTree.GetRootAsync(cancellationToken)).FindNode(diagnostic.Location.SourceSpan);
Assumes.NotNull(node?.Parent);
var newRoot = root.RemoveNode(node.Parent, SyntaxRemoveOptions.KeepNoTrivia);
Assumes.NotNull(newRoot);
return context.Document.WithSyntaxRoot(newRoot);
},
nameof(TestThirdPartyCodeFix)),
diagnostic);
}

return Task.CompletedTask;
}
}

[PartNotDiscoverable, Shared, ExportCodeFixProvider(LanguageNames.CSharp)]
private class TestThirdPartyCodeFixWithFixAll : TestThirdPartyCodeFix
{
[ImportingConstructor]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
public TestThirdPartyCodeFixWithFixAll()
{
}

public override FixAllProvider GetFixAllProvider() => BatchFixAllProvider.Instance;
}

[PartNotDiscoverable, Shared, ExportCodeFixProvider(LanguageNames.CSharp)]
private class TestThirdPartyCodeFixWithOutFixAll : TestThirdPartyCodeFix
{
[ImportingConstructor]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
public TestThirdPartyCodeFixWithOutFixAll()
{
}
}

[PartNotDiscoverable, Shared, ExportCodeFixProvider(LanguageNames.CSharp)]
private class TestThirdPartyCodeFixModifiesSolution : TestThirdPartyCodeFix
{
[ImportingConstructor]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
public TestThirdPartyCodeFixModifiesSolution()
{
}

public override FixAllProvider GetFixAllProvider() => new ModifySolutionFixAll();

private class ModifySolutionFixAll : FixAllProvider
{
public override Task<CodeAction?> GetFixAsync(FixAllContext fixAllContext)
{
var solution = fixAllContext.Solution;
return Task.FromResult<CodeAction?>(CodeAction.Create(
"Remove default case",
async cancellationToken =>
{
var toFix = await fixAllContext.GetDocumentDiagnosticsToFixAsync();
Project? project = null;
foreach (var kvp in toFix)
{
var document = kvp.Key;
project ??= document.Project;
var diagnostics = kvp.Value;
var root = await document.GetSyntaxRootAsync(cancellationToken);
Assumes.NotNull(root);
foreach (var diagnostic in diagnostics)
{
var sourceTree = diagnostic.Location.SourceTree;
Assumes.NotNull(sourceTree);
var node = (await sourceTree.GetRootAsync(cancellationToken)).FindNode(diagnostic.Location.SourceSpan);
Assumes.NotNull(node?.Parent);
var newRoot = root.RemoveNode(node.Parent, SyntaxRemoveOptions.KeepNoTrivia);
Assumes.NotNull(newRoot);
document = document.WithSyntaxRoot(newRoot);
}

solution = solution.WithDocumentText(document.Id, await document.GetTextAsync());
}

Assumes.NotNull(project);
return solution.AddDocument(DocumentId.CreateNewId(project.Id), "new.cs", SourceText.From(""));
},
nameof(TestThirdPartyCodeFix)));
}
}
}

[PartNotDiscoverable, Shared, ExportCodeFixProvider(LanguageNames.CSharp)]
private class TestThirdPartyCodeFixDoesNotSupportDocumentScope : TestThirdPartyCodeFix
{
[ImportingConstructor]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
public TestThirdPartyCodeFixDoesNotSupportDocumentScope()
{
}

public override FixAllProvider GetFixAllProvider() => new ModifySolutionFixAll();

private class ModifySolutionFixAll : FixAllProvider
{
public override IEnumerable<FixAllScope> GetSupportedFixAllScopes()
{
return new[] { FixAllScope.Project, FixAllScope.Solution, FixAllScope.Custom };
}

public override Task<CodeAction?> GetFixAsync(FixAllContext fixAllContext)
{
var solution = fixAllContext.Solution;
return Task.FromResult<CodeAction?>(CodeAction.Create(
"Remove default case",
async cancellationToken =>
{
var toFix = await fixAllContext.GetDocumentDiagnosticsToFixAsync();
Project? project = null;
foreach (var kvp in toFix)
{
var document = kvp.Key;
project ??= document.Project;
var diagnostics = kvp.Value;
var root = await document.GetSyntaxRootAsync(cancellationToken);
Assumes.NotNull(root);
foreach (var diagnostic in diagnostics)
{
var sourceTree = diagnostic.Location.SourceTree;
Assumes.NotNull(sourceTree);
var node = (await sourceTree.GetRootAsync(cancellationToken)).FindNode(diagnostic.Location.SourceSpan);
Assumes.NotNull(node?.Parent);
var newRoot = root.RemoveNode(node.Parent, SyntaxRemoveOptions.KeepNoTrivia);
Assumes.NotNull(newRoot);
document = document.WithSyntaxRoot(newRoot);
}

solution = solution.WithDocumentText(document.Id, await document.GetTextAsync());
}

Assumes.NotNull(project);
return solution.AddDocument(DocumentId.CreateNewId(project.Id), "new.cs", SourceText.From(""));
},
nameof(TestThirdPartyCodeFix)));
}
}
}
}
}
Loading