提交 7228f393 编写于 作者: C CyrusNajmabadi 提交者: GitHub

Merge pull request #14598 from CyrusNajmabadi/portFix1

Group spell checking fixes together so we can collapse them if we have a lot of fixes offered.
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp.CodeFixes.FullyQualify;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
......@@ -18,6 +20,9 @@ public class FullyQualifyTests : AbstractCSharpDiagnosticProviderBasedUserDiagno
return Tuple.Create<DiagnosticAnalyzer, CodeFixProvider>(null, new CSharpFullyQualifyCodeFixProvider());
}
protected override IList<CodeAction> MassageActions(IList<CodeAction> actions)
=> FlattenActions(actions);
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsFullyQualify)]
public async Task TestTypeFromMultipleNamespaces1()
{
......
......@@ -24,9 +24,7 @@ public partial class GenerateTypeTests : AbstractCSharpDiagnosticProviderBasedUs
}
protected override IList<CodeAction> MassageActions(IList<CodeAction> codeActions)
{
return FlattenActions(codeActions);
}
=> FlattenActions(codeActions);
#region Generate Class
......
......@@ -7,6 +7,8 @@
using Microsoft.CodeAnalysis.CSharp.CodeFixes.Spellcheck;
using Xunit;
using Roslyn.Test.Utilities;
using Microsoft.CodeAnalysis.CodeActions;
using System.Collections.Generic;
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Diagnostics.SpellCheck
{
......@@ -17,6 +19,9 @@ public class SpellCheckTests : AbstractCSharpDiagnosticProviderBasedUserDiagnost
return Tuple.Create<DiagnosticAnalyzer, CodeFixProvider>(null, new CSharpSpellCheckCodeFixProvider());
}
protected override IList<CodeAction> MassageActions(IList<CodeAction> actions)
=> FlattenActions(actions);
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsSpellcheck)]
public async Task TestNoSpellcheckForIfOnly2Characters()
{
......
Option Strict Off
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Option Strict Off
Imports Microsoft.CodeAnalysis.CodeActions
Imports Microsoft.CodeAnalysis.CodeFixes
Imports Microsoft.CodeAnalysis.Diagnostics
Imports Microsoft.CodeAnalysis.VisualBasic.CodeFixes.FullyQualify
......@@ -14,6 +15,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics.FullyQ
Return Tuple.Create(Of DiagnosticAnalyzer, CodeFixProvider)(Nothing, New VisualBasicFullyQualifyCodeFixProvider())
End Function
Protected Overrides Function MassageActions(actions As IList(Of CodeAction)) As IList(Of CodeAction)
Return FlattenActions(actions)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsFullyQualify)>
Public Async Function TestParameterType() As Task
Await TestAsync(
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports Microsoft.CodeAnalysis.CodeActions
Imports Microsoft.CodeAnalysis.CodeFixes
Imports Microsoft.CodeAnalysis.Diagnostics
Imports Microsoft.CodeAnalysis.Editor.UnitTests.Extensions
......@@ -14,6 +15,10 @@ Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.Diagnostics.Spellc
Return Tuple.Create(Of DiagnosticAnalyzer, CodeFixProvider)(Nothing, New VisualBasicSpellCheckCodeFixProvider())
End Function
Protected Overrides Function MassageActions(actions As IList(Of CodeAction)) As IList(Of CodeAction)
Return FlattenActions(actions)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.CodeActionsSpellcheck)>
Public Async Function TestNoSpellcheckForIfOnly2Characters() As Task
Dim text = <File>Class Foo
......
......@@ -70,34 +70,53 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
.Take(MaxResults);
var displayService = project.LanguageServices.GetService<ISymbolDisplayService>();
var codeActions = CreateActions(context, document, diagnostic, node, semanticModel, proposedContainers, displayService).ToImmutableArray();
foreach (var container in proposedContainers)
if (codeActions.Length > 1)
{
var containerName = displayService.ToMinimalDisplayString(semanticModel, node.SpanStart, container);
var syntaxFacts = document.Project.LanguageServices.GetService<ISyntaxFactsService>();
string name;
int arity;
syntaxFacts.GetNameAndArityOfSimpleName(node, out name, out arity);
// Actual member name might differ by case.
string memberName;
if (this.IgnoreCase)
{
var member = container.GetMembers(name).FirstOrDefault();
memberName = member != null ? member.Name : name;
}
else
{
memberName = name;
}
var codeAction = new MyCodeAction(
$"{containerName}.{memberName}",
c => ProcessNode(document, node, containerName, c));
context.RegisterCodeFix(codeAction, diagnostic);
// Wrap the spell checking actions into a single top level suggestion
// so as to not clutter the list.
context.RegisterCodeFix(new GroupingCodeAction(codeActions), context.Diagnostics);
}
else
{
context.RegisterFixes(codeActions, context.Diagnostics);
}
}
}
private IEnumerable<CodeAction> CreateActions(
CodeFixContext context, Document document, Diagnostic diagnostic,
SyntaxNode node, SemanticModel semanticModel,
IEnumerable<INamespaceOrTypeSymbol> proposedContainers,
ISymbolDisplayService displayService)
{
foreach (var container in proposedContainers)
{
var containerName = displayService.ToMinimalDisplayString(semanticModel, node.SpanStart, container);
var syntaxFacts = document.Project.LanguageServices.GetService<ISyntaxFactsService>();
string name;
int arity;
syntaxFacts.GetNameAndArityOfSimpleName(node, out name, out arity);
// Actual member name might differ by case.
string memberName;
if (this.IgnoreCase)
{
var member = container.GetMembers(name).FirstOrDefault();
memberName = member != null ? member.Name : name;
}
else
{
memberName = name;
}
var codeAction = new MyCodeAction(
$"{containerName}.{memberName}",
c => ProcessNode(document, node, containerName, c));
yield return codeAction;
}
}
......@@ -255,5 +274,13 @@ private class MyCodeAction : CodeAction.DocumentChangeAction
{
}
}
private class GroupingCodeAction : CodeAction.SimpleCodeAction
{
public GroupingCodeAction(ImmutableArray<CodeAction> nestedActions)
: base(FeaturesResources.Fully_qualify_name, nestedActions)
{
}
}
}
}
......@@ -1044,6 +1044,15 @@ internal class FeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to Fix spelling.
/// </summary>
internal static string Fix_spelling {
get {
return ResourceManager.GetString("Fix_spelling", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to from {0}.
/// </summary>
......@@ -1062,6 +1071,15 @@ internal class FeaturesResources {
}
}
/// <summary>
/// Looks up a localized string similar to Fully qualify name.
/// </summary>
internal static string Fully_qualify_name {
get {
return ResourceManager.GetString("Fully_qualify_name", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Generate {0} &apos;{1}&apos;.
/// </summary>
......
......@@ -1082,6 +1082,12 @@ This version used in: {2}</value>
<data name="Inline_variable_declaration" xml:space="preserve">
<value>Inline variable declaration</value>
</data>
<data name="Fix_spelling" xml:space="preserve">
<value>Fix spelling</value>
</data>
<data name="Fully_qualify_name" xml:space="preserve">
<value>Fully qualify name</value>
</data>
<data name="Use_expression_body_for_methods" xml:space="preserve">
<value>Use expression body for methods</value>
</data>
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
......@@ -91,12 +92,23 @@ private async Task CreateSpellCheckCodeIssueAsync(CodeFixContext context, TSimpl
}
}
var matches = results.OrderBy(kvp => kvp.Key)
.SelectMany(kvp => kvp.Value.Order())
.Where(t => t != nameText)
.Take(3)
.Select(n => CreateCodeAction(nameNode, nameText, n, document));
context.RegisterFixes(matches, context.Diagnostics);
var codeActions = results.OrderBy(kvp => kvp.Key)
.SelectMany(kvp => kvp.Value.Order())
.Where(t => t != nameText)
.Take(3)
.Select(n => CreateCodeAction(nameNode, nameText, n, document))
.ToImmutableArrayOrEmpty<CodeAction>();
if (codeActions.Length > 1)
{
// Wrap the spell checking actions into a single top level suggestion
// so as to not clutter the list.
context.RegisterCodeFix(new MyCodeAction(codeActions), context.Diagnostics);
}
else
{
context.RegisterFixes(codeActions, context.Diagnostics);
}
}
private async Task<string> GetInsertionTextAsync(Document document, CompletionItem item, CancellationToken cancellationToken)
......@@ -130,5 +142,13 @@ public SpellCheckCodeAction(string title, Func<CancellationToken, Task<Document>
{
}
}
private class MyCodeAction : CodeAction.SimpleCodeAction
{
public MyCodeAction(ImmutableArray<CodeAction> nestedActions)
: base(FeaturesResources.Fix_spelling, nestedActions)
{
}
}
}
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册