File: src\Workspaces\SharedUtilitiesAndExtensions\Compiler\Core\Formatting\Rules\Operations\FormattingOperations.cs
Web Access
Project: src\src\RoslynAnalyzers\PerformanceSensitiveAnalyzers\Core\Microsoft.CodeAnalysis.PerformanceSensitiveAnalyzers.csproj (Microsoft.CodeAnalysis.PerformanceSensitiveAnalyzers)
// 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.Generic;
using Microsoft.CodeAnalysis.Shared.Utilities;
using Microsoft.CodeAnalysis.Text;
 
namespace Microsoft.CodeAnalysis.Formatting.Rules;
 
internal static class FormattingOperations
{
    private static readonly AdjustNewLinesOperation s_preserveZeroLine = new(0, AdjustNewLinesOption.PreserveLines);
    private static readonly AdjustNewLinesOperation s_preserveOneLine = new(1, AdjustNewLinesOption.PreserveLines);
    private static readonly AdjustNewLinesOperation s_forceOneLine = new(1, AdjustNewLinesOption.ForceLines);
    private static readonly AdjustNewLinesOperation s_forceIfSameLine = new(1, AdjustNewLinesOption.ForceLinesIfOnSingleLine);
 
    private static readonly AdjustSpacesOperation s_defaultOneSpaceIfOnSingleLine = new(1, AdjustSpacesOption.DefaultSpacesIfOnSingleLine);
    private static readonly AdjustSpacesOperation s_forceOneSpaceIfOnSingleLine = new(1, AdjustSpacesOption.ForceSpacesIfOnSingleLine);
    private static readonly AdjustSpacesOperation s_forceZeroSpaceIfOnSingleLine = new(0, AdjustSpacesOption.ForceSpacesIfOnSingleLine);
 
    // As the name suggests, the line force operation is performed by force spacing
    private static readonly AdjustSpacesOperation s_forceZeroLineUsingSpaceForce = new(1, AdjustSpacesOption.ForceSpaces);
 
    /// <summary>
    /// create anchor indentation region around start and end token
    /// right after anchor token to end of end token will become anchor region
    /// </summary>
    public static AnchorIndentationOperation CreateAnchorIndentationOperation(SyntaxToken anchorToken, SyntaxToken endToken)
        => CreateAnchorIndentationOperation(anchorToken, endToken, TextSpan.FromBounds(anchorToken.Span.End, endToken.Span.End));
 
    /// <summary>
    /// create anchor indentation region more explicitly by providing all necessary information.
    /// </summary>
    public static AnchorIndentationOperation CreateAnchorIndentationOperation(SyntaxToken anchorToken, SyntaxToken endToken, TextSpan textSpan)
        => new(anchorToken, endToken, textSpan);
 
    /// <summary>
    /// create suppress region around start and end token
    /// </summary>
    public static SuppressOperation CreateSuppressOperation(SyntaxToken startToken, SyntaxToken endToken, SuppressOption option)
        => CreateSuppressOperation(startToken, endToken, TextSpan.FromBounds(startToken.SpanStart, endToken.Span.End), option);
 
    /// <summary>
    /// create suppress region around the given text span
    /// </summary>
    private static SuppressOperation CreateSuppressOperation(SyntaxToken startToken, SyntaxToken endToken, TextSpan textSpan, SuppressOption option)
        => new(startToken, endToken, textSpan, option);
 
    /// <summary>
    /// create indent block region around the start and end token with the given indentation delta added to the existing indentation at the position of the start token
    /// </summary>
    public static IndentBlockOperation CreateIndentBlockOperation(SyntaxToken startToken, SyntaxToken endToken, int indentationDelta, IndentBlockOption option)
    {
        var span = CommonFormattingHelpers.GetSpanIncludingTrailingAndLeadingTriviaOfAdjacentTokens(startToken, endToken);
        return CreateIndentBlockOperation(startToken, endToken, span, indentationDelta, option);
    }
 
    /// <summary>
    /// create indent block region around the given text span with the given indentation delta added to the existing indentation at the position of the start token
    /// </summary>
    public static IndentBlockOperation CreateIndentBlockOperation(SyntaxToken startToken, SyntaxToken endToken, TextSpan textSpan, int indentationDelta, IndentBlockOption option)
        => new(startToken, endToken, textSpan, indentationDelta, option);
 
    /// <summary>
    /// create indent block region around the start and end token with the given indentation delta added to the column of the base token
    /// </summary>
    public static IndentBlockOperation CreateRelativeIndentBlockOperation(SyntaxToken baseToken, SyntaxToken startToken, SyntaxToken endToken, int indentationDelta, IndentBlockOption option)
    {
        var span = CommonFormattingHelpers.GetSpanIncludingTrailingAndLeadingTriviaOfAdjacentTokens(startToken, endToken);
 
        return CreateRelativeIndentBlockOperation(baseToken, startToken, endToken, span, indentationDelta, option);
    }
 
    /// <summary>
    /// create indent block region around the given text span with the given indentation delta added to the column of the base token
    /// </summary>
    public static IndentBlockOperation CreateRelativeIndentBlockOperation(SyntaxToken baseToken, SyntaxToken startToken, SyntaxToken endToken, TextSpan textSpan, int indentationDelta, IndentBlockOption option)
        => new(baseToken, startToken, endToken, textSpan, indentationDelta, option);
 
    /// <summary>
    /// instruct the engine to try to align first tokens on the lines among the given tokens to be aligned to the base token
    /// </summary>
    public static AlignTokensOperation CreateAlignTokensOperation(SyntaxToken baseToken, IEnumerable<SyntaxToken> tokens, AlignTokensOption option)
        => new(baseToken, tokens, option);
 
    /// <summary>
    /// instruct the engine to try to put the give lines between two tokens
    /// </summary>
    public static AdjustNewLinesOperation CreateAdjustNewLinesOperation(int line, AdjustNewLinesOption option)
    {
        if (line == 0)
        {
            if (option == AdjustNewLinesOption.PreserveLines)
            {
                return s_preserveZeroLine;
            }
        }
        else if (line == 1)
        {
            if (option == AdjustNewLinesOption.PreserveLines)
            {
                return s_preserveOneLine;
            }
            else if (option == AdjustNewLinesOption.ForceLines)
            {
                return s_forceOneLine;
            }
            else if (option == AdjustNewLinesOption.ForceLinesIfOnSingleLine)
            {
                return s_forceIfSameLine;
            }
        }
 
        return new AdjustNewLinesOperation(line, option);
    }
 
    /// <summary>
    /// instruct the engine to try to put the given spaces between two tokens
    /// </summary>
    public static AdjustSpacesOperation CreateAdjustSpacesOperation(int space, AdjustSpacesOption option)
    {
        if (space == 1 && option == AdjustSpacesOption.DefaultSpacesIfOnSingleLine)
        {
            return s_defaultOneSpaceIfOnSingleLine;
        }
        else if (space == 0 && option == AdjustSpacesOption.ForceSpacesIfOnSingleLine)
        {
            return s_forceZeroSpaceIfOnSingleLine;
        }
        else if (space == 1 && option == AdjustSpacesOption.ForceSpacesIfOnSingleLine)
        {
            return s_forceOneSpaceIfOnSingleLine;
        }
        else if (space == 1 && option == AdjustSpacesOption.ForceSpaces)
        {
            return s_forceZeroLineUsingSpaceForce;
        }
 
        return new AdjustSpacesOperation(space, option);
    }
 
    /// <summary>
    /// return AnchorIndentationOperation for the node provided by the given formatting rules
    /// </summary>
    internal static IEnumerable<AnchorIndentationOperation> GetAnchorIndentationOperations(IEnumerable<AbstractFormattingRule> formattingRules, SyntaxNode node, SyntaxFormattingOptions options)
    {
        var chainedFormattingRules = new ChainedFormattingRules(formattingRules, options);
 
        var list = new List<AnchorIndentationOperation>();
        chainedFormattingRules.AddAnchorIndentationOperations(list, node);
        return list;
    }
 
    /// <summary>
    /// return IndentBlockOperation for the node provided by the given formatting rules
    /// </summary>
    internal static IEnumerable<IndentBlockOperation> GetIndentBlockOperations(IEnumerable<AbstractFormattingRule> formattingRules, SyntaxNode node, SyntaxFormattingOptions options)
    {
        var chainedFormattingRules = new ChainedFormattingRules(formattingRules, options);
 
        var list = new List<IndentBlockOperation>();
        chainedFormattingRules.AddIndentBlockOperations(list, node);
        return list;
    }
 
    /// <summary>
    /// return AlignTokensOperation for the node provided by the given formatting rules
    /// </summary>
    internal static IEnumerable<AlignTokensOperation> GetAlignTokensOperations(IEnumerable<AbstractFormattingRule> formattingRules, SyntaxNode node, SyntaxFormattingOptions options)
    {
        var chainedFormattingRules = new ChainedFormattingRules(formattingRules, options);
 
        var list = new List<AlignTokensOperation>();
        chainedFormattingRules.AddAlignTokensOperations(list, node);
        return list;
    }
 
    /// <summary>
    /// return AdjustNewLinesOperation for the node provided by the given formatting rules
    /// </summary>
    internal static AdjustNewLinesOperation? GetAdjustNewLinesOperation(IEnumerable<AbstractFormattingRule> formattingRules, SyntaxToken previousToken, SyntaxToken currentToken, SyntaxFormattingOptions options)
    {
        var chainedFormattingRules = new ChainedFormattingRules(formattingRules, options);
        return chainedFormattingRules.GetAdjustNewLinesOperation(previousToken, currentToken);
    }
 
    /// <summary>
    /// return AdjustSpacesOperation for the node provided by the given formatting rules
    /// </summary>
    internal static AdjustSpacesOperation? GetAdjustSpacesOperation(IEnumerable<AbstractFormattingRule> formattingRules, SyntaxToken previousToken, SyntaxToken currentToken, SyntaxFormattingOptions options)
    {
        var chainedFormattingRules = new ChainedFormattingRules(formattingRules, options);
        return chainedFormattingRules.GetAdjustSpacesOperation(previousToken, currentToken);
    }
}