/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Analyzers/CSharp/CodeFixes/RemoveConfusingSuppression/CSharpRemoveConfusingSuppressionCodeFixProvider.cs
100 строк
4 KB
Cyrus Najmabadi
Reapply "Update methods to be `async`." (#81808)
31 дек 2025, 02:04
31 дек 2025, 02:04
ba729ad
Код
Авторство
О чём код?
// 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.Immutable; using System.Composition; using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.Shared.Extensions; namespace Microsoft.CodeAnalysis.CSharp.RemoveConfusingSuppression; [ExportCodeFixProvider(LanguageNames.CSharp, Name = PredefinedCodeFixProviderNames.RemoveConfusingSuppression), Shared] [method: ImportingConstructor] [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] internal sealed partial class CSharpRemoveConfusingSuppressionCodeFixProvider() : CodeFixProvider { public const string RemoveOperator = nameof(RemoveOperator); public const string NegateExpression = nameof(NegateExpression); public override ImmutableArray<string> FixableDiagnosticIds => [IDEDiagnosticIds.RemoveConfusingSuppressionForIsExpressionDiagnosticId]; public override async Task RegisterCodeFixesAsync(CodeFixContext context) { var document = context.Document; var diagnostics = context.Diagnostics; var cancellationToken = context.CancellationToken; context.RegisterCodeFix( CodeAction.Create( CSharpAnalyzersResources.Remove_operator_preserves_semantics, c => FixAllAsync(document, diagnostics, negate: false, c), RemoveOperator), context.Diagnostics); context.RegisterCodeFix( CodeAction.Create( CSharpAnalyzersResources.Negate_expression_changes_semantics, c => FixAllAsync(document, diagnostics, negate: true, c), NegateExpression), context.Diagnostics); } private static async Task<Document> FixAllAsync( Document document, ImmutableArray<Diagnostic> diagnostics, bool negate, CancellationToken cancellationToken) { var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var editor = new SyntaxEditor(root, document.Project.Solution.Services); var generator = editor.Generator; var generatorInternal = document.GetRequiredLanguageService<SyntaxGeneratorInternal>(); foreach (var diagnostic in diagnostics) { var node = diagnostic.AdditionalLocations[0].FindNode(getInnermostNodeForTie: true, cancellationToken); Debug.Assert(node.Kind() is SyntaxKind.IsExpression or SyntaxKind.IsPatternExpression); // Negate the result if requested. var updatedNode = negate ? generator.Negate(generatorInternal, node, semanticModel, cancellationToken) : node; var isNode = updatedNode.DescendantNodesAndSelf().First( n => n.Kind() is SyntaxKind.IsExpression or SyntaxKind.IsPatternExpression); var left = isNode switch { BinaryExpressionSyntax binary => binary.Left, IsPatternExpressionSyntax isPattern => isPattern.Expression, _ => throw ExceptionUtilities.UnexpectedValue(node), }; // Remove the suppression operator. var suppression = (PostfixUnaryExpressionSyntax)left; var withoutSuppression = suppression.Operand.WithAppendedTrailingTrivia(suppression.OperatorToken.GetAllTrivia()); var isWithoutSuppression = updatedNode.ReplaceNode(suppression, withoutSuppression); editor.ReplaceNode(node, isWithoutSuppression); } return document.WithSyntaxRoot(editor.GetChangedRoot()); } public override FixAllProvider GetFixAllProvider() => FixAllProvider.Create(async (context, document, diagnostics) => await FixAllAsync( document, diagnostics, context.CodeActionEquivalenceKey == NegateExpression, context.CancellationToken).ConfigureAwait(false)); }