| File: SplitOrMergeIfStatements\CSharpMergeConsecutiveIfStatementsCodeRefactoringProvider.cs | Web Access |
| Project: src\roslyn\src\Features\CSharp\Portable\Microsoft.CodeAnalysis.CSharp.Features.csproj (Microsoft.CodeAnalysis.CSharp.Features) |
// 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. #nullable disable using System.Composition; using System.Diagnostics.CodeAnalysis; using Microsoft.CodeAnalysis.CodeRefactorings; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.CodeAnalysis.SplitOrMergeIfStatements; using Microsoft.CodeAnalysis.Text; namespace Microsoft.CodeAnalysis.CSharp.SplitOrMergeIfStatements; [ExportCodeRefactoringProvider(LanguageNames.CSharp, Name = PredefinedCodeRefactoringProviderNames.MergeConsecutiveIfStatements), Shared] internal sealed class CSharpMergeConsecutiveIfStatementsCodeRefactoringProvider : AbstractMergeConsecutiveIfStatementsCodeRefactoringProvider { [ImportingConstructor] [SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")] public CSharpMergeConsecutiveIfStatementsCodeRefactoringProvider() { } protected override bool IsApplicableSpan(SyntaxNode node, TextSpan span, out SyntaxNode ifOrElseIf) { if (node is IfStatementSyntax ifStatement) { // Cases: // 1. Position is at a child token of an if statement with no selection (e.g. 'if' keyword, a parenthesis) // 2. Selection around the 'if' keyword // 3. Selection around the header - from 'if' keyword to the end of the condition // 4. Selection around the whole if statement *excluding* its else clause - from 'if' keyword to the end of its statement if (span.Length == 0 || span.IsAround(ifStatement.IfKeyword) || span.IsAround(ifStatement.IfKeyword, ifStatement.CloseParenToken) || span.IsAround(ifStatement.IfKeyword, ifStatement.Statement)) { ifOrElseIf = ifStatement; return true; } } if (node is ElseClauseSyntax elseClause && elseClause.Statement is IfStatementSyntax elseIfStatement) { // 5. Position is at a child token of an else clause with no selection ('else' keyword) // 6. Selection around the header including the 'else' keyword - from 'else' keyword to the end of the condition // 7. Selection from the 'else' keyword to the end of the if statement's statement if (span.Length == 0 || span.IsAround(elseClause.ElseKeyword, elseIfStatement.CloseParenToken) || span.IsAround(elseClause.ElseKeyword, elseIfStatement.Statement)) { ifOrElseIf = elseIfStatement; return true; } } ifOrElseIf = null; return false; } }