/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Analyzers/CSharp/CodeFixes/UsePatternMatching/CSharpIsAndCastCheckCodeFixProvider.cs
94 строки
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.Collections.Immutable; using System.Composition; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.CSharp.Extensions; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Shared.Extensions; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp.UsePatternMatching; [ExportCodeFixProvider(LanguageNames.CSharp, Name = PredefinedCodeFixProviderNames.UsePatternMatchingIsAndCastCheck), 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 sealed partial class CSharpIsAndCastCheckCodeFixProvider() : SyntaxEditorBasedCodeFixProvider { public override ImmutableArray<string> FixableDiagnosticIds => [IDEDiagnosticIds.InlineIsTypeCheckId]; public override async Task RegisterCodeFixesAsync(CodeFixContext context) { RegisterCodeFix(context, CSharpAnalyzersResources.Use_pattern_matching, nameof(CSharpAnalyzersResources.Use_pattern_matching)); } protected override async Task FixAllAsync( Document document, ImmutableArray<Diagnostic> diagnostics, SyntaxEditor editor, CancellationToken cancellationToken) { foreach (var diagnostic in diagnostics) { cancellationToken.ThrowIfCancellationRequested(); AddEdits(editor, diagnostic, cancellationToken); } } private static void AddEdits( SyntaxEditor editor, Diagnostic diagnostic, CancellationToken cancellationToken) { var ifStatementLocation = diagnostic.AdditionalLocations[0]; var localDeclarationLocation = diagnostic.AdditionalLocations[1]; var ifStatement = (IfStatementSyntax)ifStatementLocation.FindNode(cancellationToken); var localDeclaration = (LocalDeclarationStatementSyntax)localDeclarationLocation.FindNode(cancellationToken); var isExpression = (BinaryExpressionSyntax)ifStatement.Condition; var updatedCondition = SyntaxFactory.IsPatternExpression( isExpression.Left, SyntaxFactory.DeclarationPattern( ((TypeSyntax)isExpression.Right).WithoutTrivia(), SyntaxFactory.SingleVariableDesignation( localDeclaration.Declaration.Variables[0].Identifier.WithoutTrivia()))); var trivia = localDeclaration.GetLeadingTrivia().Concat(localDeclaration.GetTrailingTrivia()) .Where(t => t.IsSingleOrMultiLineComment()) .SelectMany(t => ImmutableArray.Create(SyntaxFactory.Space, t, SyntaxFactory.ElasticCarriageReturnLineFeed)) .ToImmutableArray(); editor.RemoveNode(localDeclaration); editor.ReplaceNode(ifStatement, (i, g) => { // Because the local declaration is *inside* the 'if', we need to get the 'if' // statement after it was already modified and *then* update the condition // portion of it. var currentIf = (IfStatementSyntax)i; return GetUpdatedIfStatement(updatedCondition, trivia, ifStatement, currentIf); }); } private static IfStatementSyntax GetUpdatedIfStatement( IsPatternExpressionSyntax updatedCondition, ImmutableArray<SyntaxTrivia> trivia, IfStatementSyntax originalIf, IfStatementSyntax currentIf) { var newIf = currentIf.ReplaceNode(currentIf.Condition, updatedCondition); newIf = originalIf.IsParentKind(SyntaxKind.ElseClause) ? newIf.ReplaceToken(newIf.CloseParenToken, newIf.CloseParenToken.WithTrailingTrivia(trivia)) : newIf.WithPrependedLeadingTrivia(trivia); return newIf.WithAdditionalAnnotations(Formatter.Annotation); } }