Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// 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.Immutable;
using System.Composition;
using System.Diagnostics.CodeAnalysis;
Expand All @@ -14,55 +13,50 @@
using Microsoft.CodeAnalysis.Editing;
using Microsoft.CodeAnalysis.Shared.Extensions;

namespace Microsoft.CodeAnalysis.AddRequiredParentheses
namespace Microsoft.CodeAnalysis.AddRequiredParentheses;

[ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic, Name = PredefinedCodeFixProviderNames.AddRequiredParentheses), Shared]
[method: ImportingConstructor]
[method: SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")]
internal class AddRequiredParenthesesCodeFixProvider() : SyntaxEditorBasedCodeFixProvider
{
[ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic, Name = PredefinedCodeFixProviderNames.AddRequiredParentheses), Shared]
internal class AddRequiredParenthesesCodeFixProvider : SyntaxEditorBasedCodeFixProvider
{
[ImportingConstructor]
[SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")]
public AddRequiredParenthesesCodeFixProvider()
{
}
public override ImmutableArray<string> FixableDiagnosticIds
=> ImmutableArray.Create(IDEDiagnosticIds.AddRequiredParenthesesDiagnosticId);

public override ImmutableArray<string> FixableDiagnosticIds
=> ImmutableArray.Create(IDEDiagnosticIds.AddRequiredParenthesesDiagnosticId);
protected override bool IncludeDiagnosticDuringFixAll(Diagnostic diagnostic, Document document, string? equivalenceKey, CancellationToken cancellationToken)
=> diagnostic.Properties.ContainsKey(AddRequiredParenthesesConstants.IncludeInFixAll) &&
diagnostic.Properties[AddRequiredParenthesesConstants.EquivalenceKey] == equivalenceKey;

protected override bool IncludeDiagnosticDuringFixAll(Diagnostic diagnostic, Document document, string? equivalenceKey, CancellationToken cancellationToken)
=> diagnostic.Properties.ContainsKey(AddRequiredParenthesesConstants.IncludeInFixAll) &&
diagnostic.Properties[AddRequiredParenthesesConstants.EquivalenceKey] == equivalenceKey;
public override Task RegisterCodeFixesAsync(CodeFixContext context)
{
var firstDiagnostic = context.Diagnostics[0];
context.RegisterCodeFix(
CodeAction.Create(
AnalyzersResources.Add_parentheses_for_clarity,
GetDocumentUpdater(context),
firstDiagnostic.Properties[AddRequiredParenthesesConstants.EquivalenceKey]!),
context.Diagnostics);
return Task.CompletedTask;
}

public override Task RegisterCodeFixesAsync(CodeFixContext context)
{
var firstDiagnostic = context.Diagnostics[0];
context.RegisterCodeFix(
CodeAction.Create(
AnalyzersResources.Add_parentheses_for_clarity,
GetDocumentUpdater(context),
firstDiagnostic.Properties[AddRequiredParenthesesConstants.EquivalenceKey]!),
context.Diagnostics);
return Task.CompletedTask;
}
protected override Task FixAllAsync(
Document document, ImmutableArray<Diagnostic> diagnostics,
SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken)
{
var generator = document.GetRequiredLanguageService<SyntaxGeneratorInternal>();

protected override Task FixAllAsync(
Document document, ImmutableArray<Diagnostic> diagnostics,
SyntaxEditor editor, CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken)
foreach (var diagnostic in diagnostics)
{
var generator = document.GetRequiredLanguageService<SyntaxGeneratorInternal>();

foreach (var diagnostic in diagnostics)
{
var location = diagnostic.AdditionalLocations[0];
var node = location.FindNode(findInsideTrivia: true, getInnermostNodeForTie: true, cancellationToken);

// Do not add the simplifier annotation. We do not want the simplifier undoing the
// work we just did.
editor.ReplaceNode(node,
(current, _) => generator.AddParentheses(
current, includeElasticTrivia: false, addSimplifierAnnotation: false));
}

return Task.CompletedTask;
var location = diagnostic.AdditionalLocations[0];
var node = location.FindNode(findInsideTrivia: true, getInnermostNodeForTie: true, cancellationToken);

// Do not add the simplifier annotation. We do not want the simplifier undoing the
// work we just did.
editor.ReplaceNode(node,
(current, _) => generator.AddParentheses(
current, includeElasticTrivia: false, addSimplifierAnnotation: false));
}

return Task.CompletedTask;
}
}
237 changes: 116 additions & 121 deletions src/Analyzers/Core/CodeFixes/NamingStyle/NamingStyleCodeFixProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,164 +24,159 @@
using Microsoft.CodeAnalysis.CodeActions.WorkspaceServices;
#endif

namespace Microsoft.CodeAnalysis.CodeFixes.NamingStyles
{
namespace Microsoft.CodeAnalysis.CodeFixes.NamingStyles;

#if !CODE_STYLE // https://github.com/dotnet/roslyn/issues/42218 tracks enabling this fixer in CodeStyle layer.
[ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic,
Name = PredefinedCodeFixProviderNames.ApplyNamingStyle), Shared]
[ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic,
Name = PredefinedCodeFixProviderNames.ApplyNamingStyle), Shared]
#endif
internal sealed class NamingStyleCodeFixProvider : CodeFixProvider
{
[ImportingConstructor]
[SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")]
public NamingStyleCodeFixProvider()
{
}

public override ImmutableArray<string> FixableDiagnosticIds { get; }
= ImmutableArray.Create(IDEDiagnosticIds.NamingRuleId);
[method: ImportingConstructor]
[method: SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")]
internal sealed class NamingStyleCodeFixProvider() : CodeFixProvider
{
public override ImmutableArray<string> FixableDiagnosticIds { get; }
= ImmutableArray.Create(IDEDiagnosticIds.NamingRuleId);

public override FixAllProvider? GetFixAllProvider()
{
// Currently Fix All is not supported for naming style violations.
return null;
}
public override FixAllProvider? GetFixAllProvider()
{
// Currently Fix All is not supported for naming style violations.
return null;
}

public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
{
var diagnostic = context.Diagnostics.First();
var serializedNamingStyle = diagnostic.Properties[nameof(NamingStyle)];
Contract.ThrowIfNull(serializedNamingStyle);
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
{
var diagnostic = context.Diagnostics.First();
var serializedNamingStyle = diagnostic.Properties[nameof(NamingStyle)];
Contract.ThrowIfNull(serializedNamingStyle);

var style = NamingStyle.FromXElement(XElement.Parse(serializedNamingStyle));
var style = NamingStyle.FromXElement(XElement.Parse(serializedNamingStyle));

var document = context.Document;
var span = context.Span;
var document = context.Document;
var span = context.Span;

var root = await document.GetRequiredSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
var node = root.FindNode(span);
var root = await document.GetRequiredSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);
var node = root.FindNode(span);

if (document.GetRequiredLanguageService<ISyntaxFactsService>().IsIdentifierName(node))
{
// The location we get from the analyzer only contains the identifier token and when we get its containing node,
// it is usually the right one (such as a variable declarator, designation or a foreach statement)
// because there is no other node in between. But there is one case in a VB catch clause where the token
// is wrapped in an identifier name. So if what we found is an identifier, take the parent node instead.
// Note that this is the correct thing to do because GetDeclaredSymbol never works on identifier names.
node = node.Parent;
}
if (document.GetRequiredLanguageService<ISyntaxFactsService>().IsIdentifierName(node))
{
// The location we get from the analyzer only contains the identifier token and when we get its containing node,
// it is usually the right one (such as a variable declarator, designation or a foreach statement)
// because there is no other node in between. But there is one case in a VB catch clause where the token
// is wrapped in an identifier name. So if what we found is an identifier, take the parent node instead.
// Note that this is the correct thing to do because GetDeclaredSymbol never works on identifier names.
node = node.Parent;
}

if (node == null)
return;
if (node == null)
return;

var model = await document.GetRequiredSemanticModelAsync(context.CancellationToken).ConfigureAwait(false);
var symbol = model.GetDeclaredSymbol(node, context.CancellationToken);
var model = await document.GetRequiredSemanticModelAsync(context.CancellationToken).ConfigureAwait(false);
var symbol = model.GetDeclaredSymbol(node, context.CancellationToken);

// TODO: We should always be able to find the symbol that generated this diagnostic,
// but this cannot always be done by simply asking for the declared symbol on the node
// from the symbol's declaration location.
// See https://github.com/dotnet/roslyn/issues/16588
// TODO: We should always be able to find the symbol that generated this diagnostic,
// but this cannot always be done by simply asking for the declared symbol on the node
// from the symbol's declaration location.
// See https://github.com/dotnet/roslyn/issues/16588

if (symbol == null)
{
return;
}
if (symbol == null)
{
return;
}

var fixedNames = style.MakeCompliant(symbol.Name);
foreach (var fixedName in fixedNames)
{
context.RegisterCodeFix(
new FixNameCodeAction(
var fixedNames = style.MakeCompliant(symbol.Name);
foreach (var fixedName in fixedNames)
{
context.RegisterCodeFix(
new FixNameCodeAction(
#if !CODE_STYLE
document.Project.Solution,
symbol,
fixedName,
document.Project.Solution,
symbol,
fixedName,
#endif
string.Format(CodeFixesResources.Fix_name_violation_colon_0, fixedName),
c => FixAsync(document, symbol, fixedName, c),
equivalenceKey: nameof(NamingStyleCodeFixProvider)),
diagnostic);
}
string.Format(CodeFixesResources.Fix_name_violation_colon_0, fixedName),
c => FixAsync(document, symbol, fixedName, c),
equivalenceKey: nameof(NamingStyleCodeFixProvider)),
diagnostic);
}
}

private static async Task<Solution> FixAsync(
Document document, ISymbol symbol, string fixedName, CancellationToken cancellationToken)
{
return await Renamer.RenameSymbolAsync(
document.Project.Solution, symbol, new SymbolRenameOptions(), fixedName,
cancellationToken).ConfigureAwait(false);
}
private static async Task<Solution> FixAsync(
Document document, ISymbol symbol, string fixedName, CancellationToken cancellationToken)
{
return await Renamer.RenameSymbolAsync(
document.Project.Solution, symbol, new SymbolRenameOptions(), fixedName,
cancellationToken).ConfigureAwait(false);
}

private class FixNameCodeAction : CodeAction
{
private class FixNameCodeAction : CodeAction
{
#if !CODE_STYLE
private readonly Solution _startingSolution;
private readonly ISymbol _symbol;
private readonly string _newName;
private readonly Solution _startingSolution;
private readonly ISymbol _symbol;
private readonly string _newName;
#endif

private readonly string _title;
private readonly Func<CancellationToken, Task<Solution>> _createChangedSolutionAsync;
private readonly string _equivalenceKey;
private readonly string _title;
private readonly Func<CancellationToken, Task<Solution>> _createChangedSolutionAsync;
private readonly string _equivalenceKey;

/// <summary>
/// This code action does produce non-text-edit operations (like notifying 3rd parties about a rename). But
/// it doesn't require this. As such, we can allow it to run in hosts that only allow document edits. Those
/// hosts will simply ignore the operations they don't understand.
/// </summary>
public override ImmutableArray<string> Tags => ImmutableArray<string>.Empty;
/// <summary>
/// This code action does produce non-text-edit operations (like notifying 3rd parties about a rename). But
/// it doesn't require this. As such, we can allow it to run in hosts that only allow document edits. Those
/// hosts will simply ignore the operations they don't understand.
/// </summary>
public override ImmutableArray<string> Tags => ImmutableArray<string>.Empty;

public FixNameCodeAction(
public FixNameCodeAction(
#if !CODE_STYLE
Solution startingSolution,
ISymbol symbol,
string newName,
Solution startingSolution,
ISymbol symbol,
string newName,
#endif
string title,
Func<CancellationToken, Task<Solution>> createChangedSolutionAsync,
string equivalenceKey)
{
string title,
Func<CancellationToken, Task<Solution>> createChangedSolutionAsync,
string equivalenceKey)
{
#if !CODE_STYLE
_startingSolution = startingSolution;
_symbol = symbol;
_newName = newName;
_startingSolution = startingSolution;
_symbol = symbol;
_newName = newName;
#endif
_title = title;
_createChangedSolutionAsync = createChangedSolutionAsync;
_equivalenceKey = equivalenceKey;
}
_title = title;
_createChangedSolutionAsync = createChangedSolutionAsync;
_equivalenceKey = equivalenceKey;
}

protected override async Task<IEnumerable<CodeActionOperation>> ComputePreviewOperationsAsync(CancellationToken cancellationToken)
{
return SpecializedCollections.SingletonEnumerable(
new ApplyChangesOperation(await _createChangedSolutionAsync(cancellationToken).ConfigureAwait(false)));
}
protected override async Task<IEnumerable<CodeActionOperation>> ComputePreviewOperationsAsync(CancellationToken cancellationToken)
{
return SpecializedCollections.SingletonEnumerable(
new ApplyChangesOperation(await _createChangedSolutionAsync(cancellationToken).ConfigureAwait(false)));
}

protected override async Task<ImmutableArray<CodeActionOperation>> ComputeOperationsAsync(IProgress<CodeAnalysisProgress> progress, CancellationToken cancellationToken)
{
var newSolution = await _createChangedSolutionAsync(cancellationToken).ConfigureAwait(false);
var codeAction = new ApplyChangesOperation(newSolution);
protected override async Task<ImmutableArray<CodeActionOperation>> ComputeOperationsAsync(IProgress<CodeAnalysisProgress> progress, CancellationToken cancellationToken)
{
var newSolution = await _createChangedSolutionAsync(cancellationToken).ConfigureAwait(false);
var codeAction = new ApplyChangesOperation(newSolution);

#if CODE_STYLE // https://github.com/dotnet/roslyn/issues/42218 tracks removing this conditional code.
return ImmutableArray.Create<CodeActionOperation>(codeAction);
return ImmutableArray.Create<CodeActionOperation>(codeAction);
#else

using var operations = TemporaryArray<CodeActionOperation>.Empty;
using var operations = TemporaryArray<CodeActionOperation>.Empty;

operations.Add(codeAction);
var factory = _startingSolution.Services.GetService<ISymbolRenamedCodeActionOperationFactoryWorkspaceService>();
if (factory is not null)
{
operations.Add(factory.CreateSymbolRenamedOperation(_symbol, _newName, _startingSolution, newSolution));
}
operations.Add(codeAction);
var factory = _startingSolution.Services.GetService<ISymbolRenamedCodeActionOperationFactoryWorkspaceService>();
if (factory is not null)
{
operations.Add(factory.CreateSymbolRenamedOperation(_symbol, _newName, _startingSolution, newSolution));
}

return operations.ToImmutableAndClear();
return operations.ToImmutableAndClear();
#endif
}
}

public override string Title => _title;
public override string Title => _title;

public override string EquivalenceKey => _equivalenceKey;
}
public override string EquivalenceKey => _equivalenceKey;
}
}
Loading